Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。

尽管有上述特性,为什么不鼓励使用alloca() ?


当前回答

我认为没有人提到过这一点,但是alloca也有一些严重的安全问题,不一定是malloc所存在的(尽管这些问题也会出现在任何基于堆栈的数组中,无论是否是动态的)。由于内存是在堆栈上分配的,缓冲区溢出/下溢的后果比仅仅使用malloc要严重得多。

In particular, the return address for a function is stored on the stack. If this value gets corrupted, your code could be made to go to any executable region of memory. Compilers go to great lengths to make this difficult (in particular by randomizing address layout). However, this is clearly worse than just a stack overflow since the best case is a SEGFAULT if the return value is corrupted, but it could also start executing a random piece of memory or in the worst case some region of memory which compromises your program's security.

其他回答

原因如下:

char x;
char *y=malloc(1);
char *z=alloca(&x-y);
*z = 1;

并不是说任何人都可以编写这段代码,但是您传递给alloca的size参数几乎肯定来自某种输入,它可能恶意地目的是让您的程序分配一个像这样巨大的值。毕竟,如果大小不是基于输入,或者不可能很大,为什么不声明一个小的、固定大小的本地缓冲区呢?

几乎所有使用alloca和/或C99 vlas的代码都有严重的错误,这些错误会导致崩溃(如果你幸运的话)或特权损害(如果你不那么幸运的话)。

答案就在手册页中(至少在Linux上):

返回值 函数的作用是:返回一个指向对象开头的指针 分配空间。如果 分配的原因 堆栈溢出,程序行为未定义。

这并不是说它永远不应该被使用。我工作的一个OSS项目广泛使用它,只要你不滥用它(分配巨大的值),它是好的。一旦超过了“几百字节”的标记,就应该转而使用malloc和friends。您可能仍然会遇到分配失败,但至少您会得到一些失败的指示,而不是仅仅耗尽堆栈。

为什么没有人提到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()要分配的对象相当小,我认为这是一种比使用malloc()或其他方法更快、更方便的好技术。

换句话说,alloca(0x00ffffff)是危险的,可能会导致溢出,就像char hugeArray[0x00ffffff];是多少。小心谨慎,通情达理,你会没事的。

正如在这篇新闻组帖子中提到的,有几个原因可以解释为什么使用alloca是困难和危险的:

并非所有编译器都支持alloca。 一些编译器对alloca的预期行为有不同的解释,因此即使在支持它的编译器之间也不能保证可移植性。 一些实现存在bug。