全局(静态编译的)变量位于哪里

Where are global (statically compiled) variables located?

本文关键字:变量 于哪里 静态 编译 全局      更新时间:2023-10-16

假设我有以下程序。a分配在内存的哪个部分?cc++的行为是否相同?

// a is allocated in the ?
int a[3] = {1, 2, 3};
int main()
{
// x is allocated in the stack
int x[3] = {4, 5, 6}
// y is allocated in the heap
int* y = malloc(sizeof(int)*3);
}

它们的分配位置取决于您的机器体系结构以及编译器和链接器实现(两者都没有指定)。C++语言标准在这个问题上没有什么可说的。

静态存储中,使用标准语言。它并没有真正说明静态存储应该如何实现,只是它应该在程序的整个时间内持续,并且如果没有给出非零初始值设定项,它应该隐式零初始化。


实际上,在ELF二进制文件中,这些变量都被连接到段中,在加载时,这些段被映射到段上,这些段基本上是具有某些内存保护位的内存块。如果全局变量是可写的,并用非零值初始化,它将进入指定为.data的ELF段。zero初始化的变量将进入.bss(不是二进制映像的一部分,以节省空间),const静态变量将进入映射为只读的.rodata,以便于写保护。

编译器的binutils(如nmobjdump)可以让您窥探(依赖于实现的)细节。

这是一个实现细节,堆栈也是如此。C语言没有这样的概念。如果您的实现使用,那么它可能还使用操作系统提供的二进制格式的段。在这种情况下,静态变量被放置在databss段中,因此它们要么是程序本身(数据)的一部分,要么是OS在加载程序(bss)时分配的。

一种比较常见的方法是将默认初始化的变量放在bss中,因为这样,它们不会增加可执行文件的大小。对于常量数据,通常有一个rodata段可用,许多C编译器将字符串文本放在那里。

但底线是:你不应该在意,因为C没有指定这一点,而且有些平台不提供分段或堆。。。