C ++:函数变量声明,它在内部如何工作?

时间:2010-12-13 13:31:02

标签: c++ windows visual-studio-2008 stack

这一直困扰着我很长一段时间:让我说我有一个功能:

void test(){
    int t1, t2, t3;
    int t4 = 0;
    int bigvar[10000];
    // do something
}

计算机如何处理变量的内存分配?

我一直认为变量空间保存在计算机将读取的.exe中,这是正确的吗?但据我所知,bigvar数组在.exe中不占用10000 int个元素空间,因为它未初始化。那么当我调用函数时,它的内存分配如何工作?

3 个答案:

答案 0 :(得分:9)

这些局部变量通常使用处理器的stack来实现。这意味着编译器唯一需要做的就是计算每个变量的大小,并将它们加在一起。总和是在函数入口处更改堆栈指针的数量,并在退出时更改回来。然后访问每个变量,使其相对偏移到堆栈中的该内存块。

您的代码在Linux中编译时,在x86汇编程序中看起来像这样:

test:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $40016, %esp
        movl    $0, -4(%ebp)
        leave
        ret

在上面,常量$ 40016是四个32位整数t1, t2, t3t4所需的空间,而剩余的40000个字节代表10000个元素的数组bigvar

答案 1 :(得分:0)

除了一些笔记之外,我不能对已经说过的内容添加太多内容。实际上,您可以将局部变量放入可执行文件中,并将它们分配到数据段(并初始化)而不是堆栈段。为此,请将它们声明为static。但是,然后函数的所有调用将共享相同的变量,而在堆栈中,每次调用都会创建一组新的变量。当多个线程同时调用函数或者有递归时(试图想象),这会导致很多麻烦。这就是为什么大多数语言都使用堆栈作为局部变量而很少使用static

答案 2 :(得分:0)

在一些旧的编译器上,我遇到了静态分配数组的行为。这意味着它在加载程序时为它留出内存,并在此之后使用该空间。这种行为是不安全的(参见谢尔盖的答案),我也不希望根据标准允许它,但我在野外遇到过它。 (我对它的编译器没有记忆。)

在大多数情况下,局部变量保留在堆栈中,以及返回地址和所有其他内容。这意味着未初始化的值可能包含敏感信息。根据unwind的回答,这也包括数组。

另一个有效的实现是在堆栈上找到的变量是一个指针,并且编译器在引擎盖下进行分配和释放(可能是以异常安全的方式)。这将节省堆栈空间(必须在程序启动之前分配,并且不能轻易地扩展到x86架构),并且对于C标准VLA(可变长度数组,又名穷人的std :: vector)非常有用