Bra*_*don 9 c++ memory-management
假设我们有以下内容:
void print()
{
int a; // declaration
a = 9;
cout << a << endl;
}
int main ()
{
print();
}
Run Code Online (Sandbox Code Playgroud)
是否在函数print中分配的变量a的存储是在main中调用还是在执行到达函数内部的声明时?
这在很大程度上取决于编译器,但逻辑上,一旦声明了变量,就会分配存储.
考虑这个简单的C++示例:
// junk.c++
int addtwo(int a)
{
int x = 2;
return a + x;
}
Run Code Online (Sandbox Code Playgroud)
当GCC编译它时,会生成以下代码(;我的评论):
.file "junk.c++"
.text
.globl _Z6addtwoi
.type _Z6addtwoi, @function
_Z6addtwoi:
.LFB2:
pushl %ebp ;store the old stack frame (caller's parameters and locals)
.LCFI0:
movl %esp, %ebp ;set up the base pointer for our parameters and locals
.LCFI1:
subl $16, %esp ;leave room for local variables on the stack
.LCFI2:
movl $2, -4(%ebp) ;store the 2 in "x" (-4 offset from the base pointer)
movl -4(%ebp), %edx ;put "x" into the DX register
movl 8(%ebp), %eax ;put "a" (+8 offset from base pointer) into AX register
addl %edx, %eax ;add the two together, storing the results in AX
leave ;tear down the stack frame, no more locals or parameters
ret ;exit the function, result is returned in AX by convention
.LFE2:
.size _Z6addtwoi, .-_Z6addtwoi
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
_Z6addtwoi和.LCFI2之间的所有内容都是用于设置堆栈帧的样板代码(安全地存储前一个函数的变量等).最后一个"subl $ 16,%esp"是局部变量x的分配.
.LCFI2是您键入的实际执行代码的第一位."movl $ 2,-4(%ebp)"将值2放入变量中.(换句话说,初始化.)现在,您的空间已分配并初始化.之后,它将值加载到寄存器EDX中,然后将"8(%ebp)"中的参数移动到另一个寄存器EAX中.然后将两者加在一起,将结果保留在EAX中.现在,这是您实际输入的任何代码的结尾.剩下的只是样板.由于GCC要求在EAX中返回整数,因此不必对返回值进行任何操作."离开"指令拆除堆栈帧,"ret"指令将控制权返回给调用者.
TL; DR摘要:您可以将您的空间视为已使用块中的第一行可执行代码进行分配(配对{}).
我想我会用解释性评论清理一下,因为这是选定的答案.