Bạn có thể ngăn chúng không bị sập bằng cách không sử dụng chúng. :)
Trong mọi trường hợp, hầu như không có cách nào an toàn để sử dụng các mảng có độ dài thay đổi để làm cho cuộc sống của bạn dễ dàng hơn trừ khi bạn có giới hạn mạnh về kích thước. Mặt khác, bạn có thể sử dụng chúng có điều kiện, theo những cách như thế này:
char vla_buf[n < 1000 ? n : 1];
char *buf = sizeof vla_buf < n ? malloc(n) : vla_buf;
if (!buf) goto error;
/* ... Do stuff with buf ... */
if (buf != vla_buf) free(buf);
Trong khi điều này có vẻ như đau đớn vô dụng, nó có thể tạo sự khác biệt hiệu suất rất lớn, đặc biệt là trong các ứng dụng ren nơi có nhiều cuộc gọi đến malloc
và free
thể dẫn đến tranh chấp khóa. (Một lợi ích đáng chú ý của thủ thuật này là bạn có thể hỗ trợ các trình biên dịch cũ không có VLAs bằng cách thay thế [n < 1000 ? n : 1]
bằng 1000
, ví dụ như với macro.)
Một trường hợp tối nghĩa khác mà VLAs có thể hữu ích trong các thuật toán đệ quy mà bạn biết tổng số mục nhập được yêu cầu trên tất cả các cấp đệ quy được giới hạn bởi n
, trong đó n
đủ nhỏ để bạn tin rằng nó sẽ không tràn ngăn xếp, nhưng ở đó có thể lên tới n
mức độ đệ quy và cấp độ cá nhân sử dụng thành phần n
. Trước C99, cách duy nhất để xử lý trường hợp này mà không cần lấy n^2
không gian ngăn xếp là sử dụng malloc
. Với VLAs, bạn có thể giải quyết vấn đề hoàn toàn trên stack.
Hãy ghi nhớ, những trường hợp VLAs này thực sự có lợi là khá hiếm hoi. Thông thường VLA chỉ là một cách để lừa dối chính bạn rằng việc quản lý bộ nhớ rất dễ dàng, cho đến khi bạn nhận được bit bởi các lỗ hổng kết quả (tầm thường để khai thác) mà bạn đã tạo ra.:-)
Edit: Đối với câu hỏi ban đầu địa chỉ tốt hơn OP của:
#define MAX_VLA 10000
int bar(size_t n)
{
int arr[n <= MAX_VLA ? n : 1];
if (sizeof arr/sizeof *arr < n) return ENOMEM;
/* ... */
return 0;
}
Nguồn
2010-11-11 03:53:13
Ràng buộc của bạn có thể (hệ thống phụ thuộc, tất nhiên) không phải là "bộ nhớ" nhưng "kích thước của ngăn xếp". Và bây giờ câu hỏi có ý nghĩa hơn với tôi bởi vì tôi đã nghĩ đến việc thực hiện "trước" của bạn trên một hộp tiêu dùng hiện đại hợp lý và tự hỏi "Anh ta làm gì mà anh ấy cần một phần lớn GB?" *. Dù sao. Nếu ngăn xếp giới hạn bạn, cách "cũ" có thể tốt hơn. – dmckee
Đây chính xác là lý do tại sao VLAs không được sử dụng nhiều (một trình hỗ trợ kém trong trình biên dịch). VL C99 đơn giản là không ổn định. – VSG24