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-a
、d-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
.
我很好奇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-a
、d-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
.