在C中,我们都了解到:
int i[500]; // Array of 500 integers on stack
int *i = malloc(sizeof(int) * 500); // Array of 500 integers on heap
当函数从中推送和弹出变量时,堆栈大小会增大和缩小。但是为什么不能从堆栈中推送和弹出动态大小的数组?
答案 0 :(得分:5)
是的,他们可以:
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
答案 1 :(得分:1)
如果数组的长度在第一次分配后不会改变,那么它可以在堆栈上分配,即使它在编译时不知道它的大小。 C99在名称可变长度数组下支持此功能。该语言的早期版本可以使用非标准alloca
函数进行模拟。
然而,术语“动态大小的数组”通常假定数组可以一次又一次地无限增长,直到那里仍有可用内存,并且这样的事情在堆栈上是不可能的,因为堆栈空间在数组可能已被另一个函数调用占用。