变长数组 vs 动态分配数组

8
根据c99标准,我们可以编写以下代码,并且它是完全合法的。
int x;
scanf("%d",&x);
int ar[x];

我的问题是:如果我可以像这样分配一个数组,为什么我还需要malloc来分配可变大小的数组呢?另外,请问您能解释一下可变长度数组的分配是如何进行的吗?在深层内部,它是调用malloc来分配数组还是怎样的呢?

1
如果您希望从函数返回数组或将其存储在结构中,会发生什么?在C语言中,对象的生命周期是...有趣的。 - user166390
由于malloc()分配的数组存储在堆上,因此与其他类型的数组存储方式不同。 - Vinicius Kamakura
你可能也对这个问题感兴趣:http://stackoverflow.com/questions/6592318/how-is-dynamic-memory-allocation-better-than-array/6592437 - ShinTakezou
1
可能是[malloc分配的数组 VS 变长数组]的重复问题。(https://dev59.com/XWQn5IYBdhLWcg3wpYj0) - Ciro Santilli OurBigBook.com
@CiroSantilli,这个问题比你链接的问题早两年。 - Fingolfin
@xci13 我现在按照赞数来决定。http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-its-much-newer-and-ha - Ciro Santilli OurBigBook.com
3个回答

12

我能想到的两个原因是:

  1. 存活时间超出此堆栈帧的数组。
  2. 比堆栈更大的数组。

  1. 可以从函数返回的数组。但我想这已经包含在第1个中了。
- Vinicius Kamakura
3
@hexa,第一项就是这样了。 - David Heffernan
哦,抱歉。我用了一个不好的词语,我实际上是指那个。 不过,编译器是如何实现它的?你们能简单地解释一下吗? 再次感谢。 - Fingolfin
@Adel - 它像“普通”数组一样分配在堆栈上。它不是严格意义上的可变长度数组,因为长度是固定的,不能像c ++向量那样更改。(基本上是mallocd) - Roddy
1
@Roddy,我完全同意你的观点,但不幸的是,这些东西的官方术语确实是可变长度数组。想想看! - David Heffernan
显示剩余2条评论

5

变长数组分配(或任何数组声明)在堆栈上完成(假设使用GCC编译器)。Malloc从堆中分配内存。

堆和栈的两个优点: 1. 栈要小得多。您的可变大小数组有很大机会导致堆栈溢出。 2. 在栈上分配的项目在声明它们的函数返回后不会存活。


1
你的“优势”#2也是潜在的劣势和内存泄漏的常见原因。谨慎使用堆栈上的数组通常是良好的实践。 - Roddy

2
在C11标准中,变长数组变成了“可选项”,这意味着它们是“实现定义的”,因此不再具有可移植性。
这体现在以下两个部分:
6.7.6.2 数组声明第4节
可变长度数组是一种条件特性,实现不需要支持。
6.10.8.3 条件特性宏第1节
__STDC_NO_VLA__ 整数常量1,旨在表示实现不支持变长数组或可变修改类型。
使用malloc而不是VLA的一些优点包括:
  • malloc的实现通常从中获取内存,在大多数C实现中,堆比更大。然而,C标准中没有提到,但它们是实现全局和局部内存的常见方式。
  • 使用malloc获取的内存可以通过realloc增加或减少,但VLA不行。
  • 使用malloc获取的内存可以通过指针在程序中传递直到被free释放,但VLA只能在函数层次结构中使用。VLA在定义它的函数返回后就失效了,因为它超出了作用域。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接