内存分配和初始化是否在编译时和运行时分开进行?

时间:2019-05-31 14:56:45

标签: memory memory-management runtime dynamic-memory-allocation compile-time

当我们声明一个变量(例如int)时,我想知道在内存分配和初始化过程中涉及的步骤。还有一个指针

int x = 5;

现在在编译期间,将4个字节分配给整数x。但是何时将内存填充为值5?在编译或运行时执行期间是否进行初始化? 同样地,考虑

int x = 5;
int* p = &x;

在这两行中,分配和初始化的过程是什么。

2 个答案:

答案 0 :(得分:0)

变量初始化取决于变量的种类。全局或静态变量在编译时初始化,而自动变量在运行时完全管理。

全局变量

  • 在编译时,所有全局变量的值都是已知的。这些值由编译器写入目标文件的特定部分。

  • 在链接时,将收集所有目标文件,并为每个变量确定存储位置。如果这些地址之一分配给另一个变量,则可以知道每个变量的地址。
    结果,将生成一个可执行文件,其中包含每个部分的内容的描述(文本,数据,rodata等)。在data或rodata部分中,写入所有初始化的全局变量的值。

  • 在运行时,加载程序读取不同部分的描述并询问OS内存。然后它将所有节的内容复制到它们各自的存储位置。
    这是用在编译或链接时确定的值初始化变量的方式。
    唯一的例外是初始化为零(或未初始化)的变量。它们位于一个特殊的部分(通常称为bss)中。为了减小可执行文件的大小,这些零值未写入可执行文件中。相反,在执行main()之前,运行时过程会将bss节的所有内容设置为零。

自动变量

过程完全不同。在程序运行之前,还不知道这些变量的位置,唯一的方法是通过机器指令来计算它们的值。

因此,编译器首先确定这些var是否位于寄存器或内存中,并且在进入函数时,第一条指令将是为局部变量保留堆栈空间并初始化它们的值。这是通过常规机器指令完成的。

如果该值是另一个变量的地址(例如y =&x),
*如果x是局部(自动)变量,则通过将栈指针寄存器的内容与编译器确定的给定偏移量之和写入y来计算地址。
*如果x是全局变量或静态变量,则在链接时,一旦知道全局变量的地址,链接器就会修改编译器生成的指令,以在用于表示{{1}的寄存器或堆栈位置中写入正确的地址}。

答案 1 :(得分:0)

在某些情况下,无法在运行时进行定义: 如果user_input ==“是”:     my_var = 5 其他:     my_var = 7

但是通常这取决于负责的编译器程序员已经实现的概念。如果您使用其他编译器或语言,则情况可能会有所不同。