Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。
尽管有上述特性,为什么不鼓励使用alloca() ?
Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。
尽管有上述特性,为什么不鼓励使用alloca() ?
当前回答
正如在这篇新闻组帖子中提到的,有几个原因可以解释为什么使用alloca是困难和危险的:
并非所有编译器都支持alloca。 一些编译器对alloca的预期行为有不同的解释,因此即使在支持它的编译器之间也不能保证可移植性。 一些实现存在bug。
其他回答
为什么没有人提到GNU文档中介绍的这个例子?
https://www.gnu.org/software/libc/manual/html_node/Advantages-of-Alloca.html
使用longjmp自动完成的非本地退出(参见非本地退出) 方法退出时释放使用alloca分配的空间 调用alloca的函数。这是使用的最重要的原因 alloca
建议阅读顺序1->2->3->1:
https://www.gnu.org/software/libc/manual/html_node/Advantages-of-Alloca.html 来自非本地出口的介绍和详细信息 Alloca例子
正如在这篇新闻组帖子中提到的,有几个原因可以解释为什么使用alloca是困难和危险的:
并非所有编译器都支持alloca。 一些编译器对alloca的预期行为有不同的解释,因此即使在支持它的编译器之间也不能保证可移植性。 一些实现存在bug。
老问题了,但是没有人提到它应该被可变长度数组取代。
char arr[size];
而不是
char *arr=alloca(size);
它存在于标准C99中,并作为编译器扩展存在于许多编译器中。
进程只有有限的堆栈空间可用——远远小于malloc()可用的内存量。
通过使用alloca(),您将极大地增加获得Stack Overflow错误的机会(如果幸运的话,或者如果运气不好,则会出现莫名其妙的崩溃)。
我想没有人提到过这一点:在函数中使用alloca会阻碍或禁用一些本来可以应用在函数中的优化,因为编译器无法知道函数的堆栈帧的大小。
例如,C编译器常见的优化是在函数中消除帧指针的使用,而是相对于堆栈指针进行帧访问;所以还有一种通用寄存器。但如果在函数内部调用alloca,则sp和fp之间的差异对于函数的一部分是未知的,因此无法进行此优化。
考虑到alloca的使用很少,而且它作为标准函数的不光彩地位,编译器设计人员很可能会禁用任何可能导致alloca出现问题的优化,如果要使它与alloca一起工作需要付出更多的努力的话。
更新: 由于变长局部数组已经添加到C语言中,并且由于这些向编译器提出了与alloca非常相似的代码生成问题,我看到“使用的罕见性和阴暗状态”不适用于底层机制;但是我仍然怀疑使用alloca或VLA会损害使用它们的函数中的代码生成。我欢迎来自编译器设计人员的任何反馈。