Почему динамически изменяемый массив не может быть выделен в стеке?
В C мы все узнали, что:
int i[500]; // Array of 500 integers on stack
int *i = malloc(sizeof(int) * 500); // Array of 500 integers on heap
Размер стека растет и уменьшается по мере того, как функции выталкивают и выталкивают из него переменные. Но почему массив динамического размера не может быть вытеснен и извлечен из стека?
2 ответа:
Да, они могут:
Http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
Автоматические массивы переменной длины разрешены в стандарте ISO C99, и в качестве расширение GCC принимает их в режиме C90 и в C++. Эти массивы являются объявляется, как и любые другие автоматические массивы, но с длиной, которая равна не постоянное выражение. Хранилище выделяется в точке объявление и освобождение, когда область блока, содержащая декларация выходит. Для Пример:
FILE * concat_fopen (char *s1, char *s2, char *mode) { char str[strlen (s1) + strlen (s2) + 1]; strcpy (str, s1); strcat (str, s2); return fopen (str, mode); }
Простой тест:
$ cat testarray.c #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { size_t n = atol(argv[1]), i; printf("array size: %lu\n", n); int a[n]; for (i=0; i<n; ++i) { a[i] = i; } printf("%d\n", a[0]); return 0; } $ ./a.out 100000 array size: 100000 0 $ ./a.out 1000000 array size: 1000000 0 $ ./a.out 10000000 array size: 10000000 Segmentation fault $ ./a.out 100000000 array size: 100000000 Segmentation fault
Если длина массива не изменится с момента первого выделения, то он может быть выделен в стек, даже если его размер не известен на момент компиляции. C99 поддерживает это под именем массивы переменной длины. Предыдущие версии языка могли имитировать то же самое с помощью нестандартной функции
alloca
.Однако термин "динамически размерный массив" обычно предполагает, что массив может расти позже снова и снова, до тех пор, пока не останется доступной памяти, и такая вещь на самом деле это невозможно в стеке, потому что пространство стека после массива может быть уже занято другим вызовом функции.