引用 BUGS 部分的第二段,来自 alloca(3) 的联机帮助页



我没有看到这会如何发生。以以下代码为例:

void f(int a, void * b, int c);

int
main(void)
{
    f(1, alloca(100), 2);
}

根据我的理解,allocamain 的堆栈帧向下扩展 100 个字节(通过修改堆栈指针寄存器),然后指向该堆栈内存块的指针(以及 2 个 int s)在 f 的堆栈帧上传递。所以分配的空间不应该在 abc 的中间,实际上它应该在不同的帧上(在这种情况下是在 main 的帧上)。

那么这里有什么误解呢?

最佳答案

首先,请立即注意 alloca is not standard 。它是对平台的扩展,希望通过潜在地动态消耗自动变量空间来为程序员提供更多方式来吊死自己,以提高速度而不是基于其他技术(堆等)的慢速动态内存分配器。 (是的,我的意见,但里面有很多真理)。

也就是说,考虑一下:

你以前写过编译器吗? There is no standard guarantee of evaluation order of function arguments 。因此,假设某个平台选择通过最终从右到左(他们的选择)将以下内容推送到激活堆栈中来构建 activation record 以调用 f:

  • 将 2 压入事件记录堆栈空间。
  • 执行 alloca(100) ,它吸收同一个堆栈,该堆栈包含由另外 100 个 char 构建的调用激活记录。
  • 将(2)的结果,一个 void* ,插入事件记录堆栈空间。
  • 将 1 压入事件记录堆栈空间。
  • 调用 call f,将 main 中的返回地址压入事件记录堆栈空间。

  • 现在,把你自己想象成函数 f 。您希望在哪里找到函数的第三个参数?嗯……

    这只是一个例子,说明如何将 alloca 空间扔到可能导致问题的地方。

    关于c - 为什么不能在函数参数列表中使用 alloca?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41919656/

    10-11 11:34