这个“老”问题有很多有趣的答案,甚至还有一些相对较新的答案,但我没有发现任何提及这个问题的答案。
如果使用得当,请谨慎使用alloca()
(如果可能在整个应用程序范围内)一致地使用,以处理较小的可变长度分配(或C99 VLA,如果可用),与使用固定长度的超大局部数组的等效实现相比,它可能导致总体堆栈增长降低。。因此,如果仔细使用它alloca()
可能对您的堆栈有好处。
我找到了那个报价。...好,我把那个报价编了起来。但实际上,请考虑一下...。
@j_random_hacker在其他答案下的评论中是非常正确的:避免使用过alloca()
大的本地数组来支持程序不会使程序免受堆栈溢出的影响(除非您的编译器足够老,可以内联使用的函数,alloca()
在这种情况下,您应该升级,或者除非您使用alloca()
内部循环,否则在这种情况下,您不应该使用alloca()
内部循环)。
我曾在台式机/服务器环境和嵌入式系统上工作。许多嵌入式系统根本不使用堆(它们甚至不支持堆),原因包括人们认为动态分配的内存是有害的,这是由于应用程序存在内存泄漏的风险,一次会重新启动数年,或者更合理的理由认为动态内存是危险的,因为无法确定某个应用程序永远不会将其堆碎片化为错误的内存耗尽点。因此,嵌入式程序员几乎没有其他选择。
alloca()
(或VLA)可能只是完成这项工作的合适工具。
我一次又一次地看到程序员使堆栈分配的缓冲区“大到足以应付任何可能的情况”。在深度嵌套的调用树中,重复使用该(反-)模式会导致堆栈使用过度。(想象一下,调用树深度为20层,由于不同的原因,在每个层上,该函数盲目地过度分配1024个字节的缓冲区“为了安全起见”,而通常它只会使用16个或更少的缓冲区,极少数情况下可能会使用更多。)一种替代方法是使用alloca()
或VLA并仅分配函数所需的堆栈空间,以避免不必要地增加堆栈负担。希望当调用树中的一个函数需要比正常更大的分配时,调用树中的其他函数仍在使用其正常的小分配,并且与每个函数盲目地过度分配本地缓冲区的情况相比,整个应用程序堆栈的使用率要低得多。 。
但是,如果您选择使用alloca()
...
根据此页面上的其他答案,似乎VLA应该是安全的(如果从循环内调用,则不会复合堆栈分配),但是如果您使用alloca()
,请注意不要在循环内使用它,并且确保如果有可能在另一个函数的循环中调用该函数,则不能将其内联。