繁体   English   中英

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

[英]C++: Function variable declarations, how does it work internally?

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

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

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

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

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

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

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

在上面,常量$ 40016是四个32位int t1, t2, t3t4所需的空间,而剩余的40000个字节占10000个元素阵列bigvar

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM