内存分配变量

T.J*_*.J. 1 c c++ variables

我很困惑.自动,静态和全局变量的分配是在编译时还是在运行时进行?

我知道的是,在编译时,源代码被翻译成机器语言.

当编译器找到类似的语句时int a;,它会写入指令.在编译时是否会发生任何额外的事情,比如内存分配?

执行.exe文件时会发生什么?

计算机(OS)或编译器是否会在运行时或编译时分配足够的内存来保存整数.

还有人说全局变量的地址是编译时常量.这是什么意思? 请帮助解决每个问题,尤其是最后一个问题.

Jas*_*son 6

静态全局变量在编译时或运行时分配内存资源.这取决于静态变量是否为零初始化,或者它们是否具有初始常量值.例如,代码就像

//global variable with internal linkage
static int array[100];
Run Code Online (Sandbox Code Playgroud)

不会占用可执行文件中的任何空间...换句话说,编译器/链接器不会在该数组的可执行文件中分配内存,因为它不包含任何内容.它将留下一个存根,指示何时启动可执行文件,必须为该数组分配内存.一旦启动可执行文件,操作系统就会看到链接器留下的存根,并为数组(以及堆的其他内存等)分配和零初始化内存.另一方面,

//global variable with internal linkage
static int array[100] = { 1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

将占用可执行文件中的空间,因为它在编译时使用常量值进行初始化.因此,编译器将在data它生成的程序集文件的部分中发出代码,为该数组分配存储空间.然后,链接器将正确布局链接到最终可执行文件的所有程序集文件的数据部分和代码部分.当OS将可执行文件加载到内存中时,该数组的内存已经是可执行文件内存"foot-print"的一部分.

自动变量,因为它们在代码执行期间在堆栈上分配,在运行时分配.

还有人说全局变量的地址是编译时常量.

这有点误导......在C中,在链接器创建可执行文件之前,您无法知道任何全局变量的确切内存地址,并且操作系统已将可执行文件加载到内存中.这样做的唯一方法就是手动组装文件并创建一个由操作系统专门加载到给定地址的平面二进制文件,但现代操作系统不允许你这样做.相反,链接器为全局变量的地址赋予占位符,以便在操作系统在运行时加载可执行文件时,可以用正确的值替换它们.因此,虽然内存地址是"常量"的,因为它在程序运行时不会随时间改变,但它的实际值不会在编译时分配.