为什么不能在堆栈上分配动态大小的数组?

时间:2014-04-17 08:39:59

标签: c arrays memory allocation

在C中,我们都了解到:

int i[500]; // Array of 500 integers on stack
int *i = malloc(sizeof(int) * 500); // Array of 500 integers on heap

当函数从中推送和弹出变量时,堆栈大小会增大和缩小。但是为什么不能从堆栈中推送和弹出动态大小的数组?

2 个答案:

答案 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函数进行模拟。

然而,术语“动态大小的数组”通常假定数组可以一次又一次地无限增长,直到那里仍有可用内存,并且这样的事情在堆栈上是不可能的,因为堆栈空间在数组可能已被另一个函数调用占用。