malloced数组VS. 可变长度数组

lin*_*usz 28 c malloc variable-length-array

有两种方法可以为数组分配内存,其大小在开始时是未知的.最常见的方式是使用malloc这样的

int * array;
... // when we know the size
array = malloc(size*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

但是在我们知道尺寸后,在C99中定义数组也是有效的.

... // when we know the size
int array[size];
Run Code Online (Sandbox Code Playgroud)

他们完全一样吗?

Jen*_*ens 39

不,他们不是完全一样的.虽然两者都允许您存储相同数量和类型的对象,但请记住:

  • 你可以使用free()一个malloced数组,但你不能使用free()一个可变长度的数组(虽然它超出范围并且一旦留下封闭块就不再存在).在技​​术术语中,它们具有不同的存储持续时间:分配给malloc而不是自动用于可变长度数组.
  • 尽管C没有堆栈的概念,但许多实现从堆栈中分配可变长度数组,同时malloc堆中分配.这是堆栈受限系统上的一个问题,例如许多嵌入式操作系统,其中堆栈大小为大约kB,而堆大得多.
  • malloc与使用可变长度数组一样,测试失败的分配也更容易.
  • malloced内存的大小可以改变realloc(),而VGA则不能(更准确地说,只能通过使用不同的数组维度再次执行该块 - 这会丢失先前的内容).
  • 托管的C89实现仅支持malloc().
  • 托管的C11实现可能不支持可变长度数组(然后必须__STDC_NO_VLA__根据C11 6.10.8.3 定义为整数1).
  • 我错过的其他一切:-)

  • @KeithThompson:确切地说,数组的标识符超出了封闭块末尾的范围.范围是标识符(名称)的属性,而不是对象的属性.一个对象可以在其标识符范围之外访问,就像它的地址被传递给另一个例程一样. (6认同)
  • @EricPostpischil:你已经嘲笑我了! (5认同)
  • VLA超出了封闭块末尾的范围(不再可见),因为它具有块范围.它在块的末尾不再存在,因为它具有自动存储持续时间.两件不同的事情. (3认同)
  • @Jens *C 没有堆栈的概念到底是什么意思*?我第一次听到这个,很感兴趣。你能详细说明一下吗? (2认同)
  • @Daniel main() 是入口,但可能不是出口。其他终止程序的函数有 exit()、quick_exit()、_Exit() 和 abort()。 (2认同)