Twi*_*day 2 c memory-management compilation
当我写作
int main()
{
int j;
}
Run Code Online (Sandbox Code Playgroud)
'j'的内存是在编译时分配的,但是在编译期间?当内存分配给变量时,编译的各个阶段是什么?如果j是全局的怎么办?
在编译时,你的'int j'将在应用程序启动时分配,当应用程序进入main()作用域时(实际上它不会在技术上得到分配,因为正在使用堆栈),全局变量将在运行时分配在进入main()范围之前.
在C中,main的编译与其他每个函数的编译方式相同:在main中声明的任何变量都将在堆栈中"分配".堆栈帧是单个函数调用使用的堆栈部分.该框架包含函数中使用的所有本地的插槽.此内存被认为是临时的,因为当函数返回时,此帧将从堆栈中弹出.
C编译器将为全局变量分配静态地址.该地址被认为是二进制文件"图像"的一部分,因此在内存中具有静态位置.C编译器知道每种类型的大小,因此它可以为每个全局变量在二进制的内存布局中留出适当的空间量.然后,访问此变量的任何代码都将简单地引用此地址.
您可以使用以下代码检查变量的地址:
#include<stdio.h>
int i;
void foo(int n)
{
if(n > 2)
return;
printf("From foo &n = %xd\n", &n);
printf("From foo &i = %xd\n", &i);
foo(n+1);
}
int main()
{
printf("&i = %xd\n", &i);
foo(0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行此代码会产生类似于的输出:
./a.out
&i = 600934d
From foo &n = 38bc4efcd
From foo &i = 600934d
From foo &n = 38bc4eccd
From foo &i = 600934d
From foo &n = 38bc4e9cd
From foo &i = 600934d
Run Code Online (Sandbox Code Playgroud)
你应该注意两件事:
foo随着每次调用foo而变化.实际上,它会随着堆栈向下增长而每次都减少.