是否需要从堆栈中分配C可变长度数组?

ASh*_*lly 6 c heap-memory variable-length-array

从我们的嵌入式系统代码中删除对malloc和calloc的所有调用后,我惊讶地发现malloc仍然被链接.调用图指向一个没有显式*alloc调用的函数,并且没有调用任何可能分配的库函数,比如strdup.
我必须查看生成的程序集才能意识到它是由于包含VLA的内联函数.

我认为VLA必须是堆栈分配的.这个编译器坏了吗?

Joh*_*ode 8

没有要求从堆栈中分配VLA(语言标准甚至没有提到堆栈或堆).唯一的要求如下:

6.2.4对象的存储持续时间
...
7对于具有可变长度数组类型的对象,其生命周期从对象的声明扩展,直到程序的执行离开声明的范围.35)如果以递归方式输入范围,则每次都会创建一个新的对象实例.对象的初始值是不确定的.
35)离开包含声明的最里面的块,或者在声明之前跳转到该块或嵌入块中的某个点,留下声明的范围.

鉴于此,从堆栈中分配是有意义的,但对于非常大的对象,这可能是不可能的,并且可以从堆或一些其他存储器段中分配这样的对象.簿记取决于实施.


Adr*_*ian 5

不,它们不必是堆栈分配的。alloca如果您希望它在堆栈中,我会使用它。

来源 1:https : //stackoverflow.com/a/2035292/283342

其次,VLA 通常在堆栈上分配,但由于其大小可变,通常情况下,在编译时无法知道其在内存中的确切位置。出于这个原因,底层实现通常必须将其实现为指向内存块的指针。这引入了一些额外的内存开销(对于指针),由于上述原因,这再次完全无关紧要。这也引入了轻微的性能开销,因为我们必须读取指针值才能找到实际的数组。这与访问 malloc-ed 数组时获得的开销相同(并且不使用命名的编译时大小的数组)。

来源 2:https : //en.wikipedia.org/wiki/Variable-length_array

语言对 VLA 的支持可能隐藏的一个问题是底层内存分配问题:在堆和堆栈之间有明显区别的环境中,可能不清楚其中哪一个(如果有的话)将存储VLA。