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

当你总是可以在堆栈上分配一个足够大的固定大小的缓冲区来满足所有用途时,你为什么要使用alloca()? 这不是一个修辞问题……

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

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

你是否应该是另一个问题 – 它不是标准的,也没有办法判断它是否会导致堆栈溢出。

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

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

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

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

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

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

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

几乎从不需要alloca()函数; 为了内存分配的目的,你可以在C中使用malloc() / free() (或者是C ++中可能的集合之一)并实现几乎相同的实际效果。 这具有更好地应对较小堆栈尺寸的优点。

但是我已经看到[1]一个合法的(如果hacky!)使用它:用于检测Windows上可能的堆栈溢出; 如果分配(您想要访问的斜坡空间量)失败,那么您已经出局但有足够的空间来优雅地恢复。 它包含在__try / __except因此它不会崩溃,并且需要额外的汇编程序技巧来避免gcc引发的麻烦。 正如我所说,一个黑客。 但是一个聪明的东西,是我见过的唯一有效的alloca()用途。

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


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

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

例如,在glibc的segfault.c中 ,我们有:

  /* 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 *)); /* ... */ }