variable length array/alloca 在栈中分配到哪里

Where does variable length array/alloca allocate in stack

我很好奇alloca()函数是如何工作的,因此,我写了一个简单的测试程序如下:

int test() {
    int a = 0;
    int e;
    char tmp2[a]; //alloca
    int d;
    char* tmp3 = new char[2];
    tmp2[100] = 1;
    return 0;
}

int main(int argc, char** argv) {
    test();
    return 0;
}

根据文档,alloca()将在堆栈中分配内存。我 运行 使用 gdb 的程序并计算出 (char*)&tmp2 - (char*)a = -44 这意味着它们之间有 44 个字节,而 e-ad-e、[=17= 的地址之间的距离] 是 4 个字节。我真的不明白编译器如何在堆栈中分配一个可变长度的数组,希望有人能告诉我这 44 个字节是什么意思。

char tmp2[a];

其中 a 是一个非常量整数,使用称为 可变长度数组 VLAs 的 C99 功能.

该功能在标准 C++ 中不可用,尽管它是 g++ 编译器在非一致性模式下支持的语言扩展。

未指定如何为 VLA 分配内存。它可能在机器堆栈上,如 alloca,也可能是动态分配的内存。

alloca() 不是标准的一部分。它被认为是 compiler/machine 依赖。因此内在函数仅属于实现。

话虽如此,如果我们谈论 x86 机器,那么堆栈操作是通过使用专用堆栈指针寄存器完成的 - sp / esp / rsp (16/ 32/64 位代码),其中包含压入堆栈的最后一个 word/dword/qword 的地址。要保留更多内存,我们只需从 sp 寄存器中减去一些值。

因此 "typical" alloca(x) 在 x86 中的实现只是一条 CPU 指令:sub sp, x.