“编译时分配的内存”是什么意思?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

在像C和C++这样的编程语言中,人们通常会引用静态和动态内存分配。我理解这个概念,但是“在编译期间分配(保留)所有内存”这句话总是令我困惑。

据我了解,编译将高级C / C ++代码转换为机器语言并输出可执行文件。在编译的文件中如何“分配”内存?是不是所有的虚拟内存管理内存总是分配在内存中?

按定义,内存分配是不是运行时概念?

如果我在C/C++代码中创建一个1KB静态分配的变量,是否会增加相同数量的可执行文件的大小?

MSDN:

Back To Basics: Memory allocation, a walk down the history

提问于
用户回答回答于

在编译时分配的内存意味着编译器在编译时解析某些内容将在进程内存映射中分配的地方。

例如,考虑一个全局数组:

int array[100];

编译器在编译时知道数组的大小和大小int,因此它在编译时知道数组的整个大小。此外,全局变量默认情况下具有静态存储持续时间:它分配在进程内存空间的静态内存区域(.data / .bss节)中。根据这些信息,编译器会在编译期间决定该阵列将在哪个静态存储区中的哪个地址

当然,这些内存地址是虚拟地址。该程序假定它有自己的整个内存空间(例如,从0x00000000到0xFFFFFFFF)。这就是为什么编译器可以做一些假设,例如“好吧,数组将在地址0x00A33211”。在运行时,MMU和OS将地址转换为真实/硬件地址。

值初始化静态存储的东西有点不同。例如:

int array[] = { 1 , 2 , 3 , 4 };

在我们的第一个例子中,编译器只决定了数组的分配位置,将该信息存储在可执行文件中。 在值初始化的情况下,编译器还会将数组的初始值注入到可执行文件中,并添加代码,告诉程序加载程序在程序启动时数组分配后应该填充这些值。

以下是由编译器生成的程序集的两个示例(带x86目标的GCC4.8.1):

C++代码:

int a[4];
int b[] = { 1 , 2 , 3 , 4 };

int main()
{}

输出:

a:
    .zero   16
b:
    .long   1
    .long   2
    .long   3
    .long   4
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $0, %eax
    popq    %rbp
    ret
用户回答回答于

在编译时分配的内存仅仅意味着在运行时不会有进一步的分配 - 不会调用malloc,new或其他动态分配方法。即使你不需要所有的内存,你也会有固定的内存使用量。

内存在运行时间之前未被使用,但在执行之前立即开始其分配由系统处理。

如果我在C / C ++代码中创建一个1KB静态分配的变量,是否会增加相同数量的可执行文件的大小?

简单地声明静态不会增加超过几个字节的可执行文件的大小。用非零的初始值声明它(为了保持初始值)。链接器只是简单地将这个1KB数量添加到系统加载程序在执行之前立即为其创建的内存要求。

扫码关注云+社区