在哪些情况下alloca()有用吗?

时间:2010-08-10 18:59:42

标签: c++ c stack alloca

为什么你总是想要在堆栈上分配固定大小的缓冲区以便适合所有用途时使用alloca()?这不是一个修辞问题......

6 个答案:

答案 0 :(得分:2)

如果缓冲区的大小在运行时变化,或者有时只需要它,则可能会有用:在每次调用中,这将比使用固定大小的缓冲区使用更少的堆栈空间。特别是如果函数在堆栈中高或递归。

答案 1 :(得分:0)

从不 - 它不是C ++的一部分,在C中没用。但是,你不能在堆栈上分配“静态缓冲区” - 静态缓冲区在编译时分配,而不是在堆栈上分配。

alloca()的重点当然是它不是固定大小的,它在堆栈上,并且当函数退出时它会自动释放。 C ++和C都有更好的机制来处理这个问题。

答案 2 :(得分:0)

如果无法知道编译时可能需要的最大大小,可能需要使用它。

是否another question - 它不是标准的,也无法判断它是否会导致堆栈溢出。

答案 3 :(得分:0)

  

在哪些情况下,alloca()有用吗?

我见过alloca的唯一一次是Open Dynamics Engine。 AFAIK他们用它分配了巨大的矩阵(所以编译的程序可能需要100MB的堆栈),当函数返回时会自动释放(看起来像smartpointer ripoff给我)。这是很久以前的事了。

虽然它可能比new / malloc快得多,但我仍然认为这是一个坏主意。 当场景变得太复杂而无法处理时,而不是礼貌地耗尽RAM程序可能会因堆栈溢出(即误导)而崩溃。不是一个好的行为,IMO,特别是对于物理引擎,在那里你可以很容易地期望有人将数千块砖扔进场景中,看看当它们全部碰撞时会发生什么。另外,您必须手动设置堆栈大小 - 即在具有更多RAM的系统上,程序仍将受到堆栈大小的限制。

  

堆栈上的固定大小缓冲区是否足以满足所有用途?这不是一个修辞问题......

如果您需要固定大小的缓冲区用于所有用途,那么您也可以将其放入静态/全局变量或使用堆内存。

答案 4 :(得分:0)

几乎不需要alloca()功能;出于内存分配的目的,您可以在C中使用malloc() / free()(或者在C ++中使用其中一种可能性)并实现几乎相同的实际效果。这样做的优点是可以更好地应对较小的堆栈尺寸。

然而我见过 [1] 一个合法的(如果hacky!)使用它:用于检测Windows上潜在的堆栈溢出;如果分配(你想要访问的斜坡空间量)失败了,你就出去了但是有足够的空间来优雅地恢复。它被包裹在__try / __except中,因此它不会崩溃,并且需要额外的汇编程序技巧来避免gcc引发的麻烦。正如我所说,一个黑客。但这是我见过alloca()唯一有效的用途。

但不要这样做。最好编写代码,不需要这样的游戏。


[1] 它是在Tcl 8.4中(可能是早期版本的Tcl)。它在以后的版本中删除了。后来的版本删除它,因为它很挑剔,非常棘手和深刻的麻烦。 8.6使用执行引擎的无堆栈实现而不是那种funkiness。

答案 5 :(得分:0)

当您无法可靠地使用alloca()(或C ++中的malloc()或其他内存分配器)时,使用new 可能是合理的,或者根本不可能,但你可以假设你的堆栈上有更多可用空间 - 也就是说,当你无法做其他任何事情时。

例如,在glibc的{​​{3}}中,我们有:

 /* This function is called when a segmentation fault is caught.  The system
    is in an unstable state now.  This means especially that malloc() might
    not work anymore.  */
static void
catch_segfault (int signal, SIGCONTEXT ctx)
{
    void **arr;

    /* ... */

    /* Get the backtrace.  */
    arr = alloca (256 * sizeof (void *));

    /* ... */
}