Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。
尽管有上述特性,为什么不鼓励使用alloca() ?
Alloca()在堆栈上分配内存,而不是像malloc()那样在堆上分配内存。因此,当我从例程返回时,内存被释放。这实际上解决了动态分配内存的问题。通过malloc()释放分配的内存是一个非常令人头痛的问题,如果以某种方式错过释放会导致各种内存问题。
尽管有上述特性,为什么不鼓励使用alloca() ?
当前回答
答案就在手册页中(至少在Linux上):
返回值 函数的作用是:返回一个指向对象开头的指针 分配空间。如果 分配的原因 堆栈溢出,程序行为未定义。
这并不是说它永远不应该被使用。我工作的一个OSS项目广泛使用它,只要你不滥用它(分配巨大的值),它是好的。一旦超过了“几百字节”的标记,就应该转而使用malloc和friends。您可能仍然会遇到分配失败,但至少您会得到一些失败的指示,而不是仅仅耗尽堆栈。
其他回答
alloca并不比变长数组(VLA)更糟糕,但它比在堆上分配更危险。
在x86上(最常见的是在ARM上),堆栈向下增长,这带来了一定的风险:如果你不小心写超出了用alloca分配的块(例如由于缓冲区溢出),那么你将覆盖你的函数的返回地址,因为它位于堆栈的“上面”,即在你分配的块之后。
这样做的后果是双重的:
程序将崩溃的壮观,它将不可能告诉为什么或哪里崩溃(堆栈将最有可能unwind到一个随机地址,由于覆盖的帧指针)。 它使缓冲区溢出的危险增加了许多倍,因为恶意用户可以制作一个特殊的有效负载,将其放在堆栈上,因此最终可以执行。
相反,如果你在堆上写超过一个块,你“只是”得到堆损坏。程序可能会意外终止,但会正确地展开堆栈,从而减少恶意代码执行的机会。
进程只有有限的堆栈空间可用——远远小于malloc()可用的内存量。
通过使用alloca(),您将极大地增加获得Stack Overflow错误的机会(如果幸运的话,或者如果运气不好,则会出现莫名其妙的崩溃)。
A place where alloca() is especially dangerous than malloc() is the kernel - kernel of a typical operating system has a fixed sized stack space hard-coded into one of its header; it is not as flexible as the stack of an application. Making a call to alloca() with an unwarranted size may cause the kernel to crash. Certain compilers warn usage of alloca() (and even VLAs for that matter) under certain options that ought to be turned on while compiling a kernel code - here, it is better to allocate memory in the heap that is not fixed by a hard-coded limit.
alloca() is very useful if you can't use a standard local variable because its size would need to be determined at runtime and you can absolutely guarantee that the pointer you get from alloca() will NEVER be used after this function returns. You can be fairly safe if you do not return the pointer, or anything that contains it. do not store the pointer in any structure allocated on the heap do not let any other thread use the pointer The real danger comes from the chance that someone else will violate these conditions sometime later. With that in mind it's great for passing buffers to functions that format text into them :)
正如在这篇新闻组帖子中提到的,有几个原因可以解释为什么使用alloca是困难和危险的:
并非所有编译器都支持alloca。 一些编译器对alloca的预期行为有不同的解释,因此即使在支持它的编译器之间也不能保证可移植性。 一些实现存在bug。