我对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
,tmp3-d
的地址之间的距离是4个字节。我真的无法理解编译器如何在堆栈中分配可变长度数组,并希望有人能告诉我44字节的含义是什么。
答案 0 :(得分:3)
alloca()
不是标准的一部分。它被认为是编译器/机器相关的。因此,内在函数仅属于实现。
话虽如此,如果我们谈论x86机器,那么通过使用专用堆栈指针寄存器来完成堆栈操作 - sp
/ esp
/ rsp
(16/32 / 64位代码),包含压入堆栈的最后一个字/双字/ qword的地址。要保留更多内存,我们只需从sp
寄存器中减去一些值。
因此,x86中的“典型”alloca(x)
实现只是一条CPU指令:sub sp, x
。
答案 1 :(得分:1)
char tmp2[a];
其中a
是一个非常数整数,使用名为可变长度数组或 VLA 的C99功能。
该功能在标准C ++中不可用,尽管它是g ++编译器在不符合模式下支持的语言扩展。
未指定如何为VLA分配内存。它可能在机器堆栈上,如alloca
,也可能是动态分配的内存。