添加未初始化全局变量后size命令结果未变?C内存布局疑问
关于C语言内存布局的两个问题解答
为什么添加未初始化全局变量后bss段大小没变化?
有两个最可能的原因:
- 未使用变量被编译器/链接器优化消除:如果代码里仅声明了
int x;但从未使用它,gcc在链接阶段会自动丢弃这个未被引用的全局变量,相当于它从未存在过,自然不会改变bss段的大小。你可以尝试在main函数里引用x(比如打印x的值),再编译执行size命令,就能看到bss段大小变化。 - 段大小的对齐机制:操作系统和编译器对内存段的大小有对齐要求(比如按4KB页面对齐,或更小的对齐单位)。如果原本8字节的bss段已经是对齐后的最小单位,添加4字节后总大小12字节仍落在同一个对齐块内,
size命令显示的是对齐后的段大小,所以看起来没有变化。你可以尝试添加大量未初始化变量(比如100个int),再观察bss段大小是否明显增长,就能验证这个机制。
初始状态下data段和bss段的内容是什么?
- data段(512字节):这个段存储已初始化的全局变量、静态变量,以及编译器/运行时库默认添加的可读写初始化数据。比如你声明
int global_val = 10;,这个变量就会存在data段,初始值就是10。即使你没写任何自定义全局变量,编译器也会生成一些运行时必需的辅助数据(比如全局状态标记、初始化相关的变量),对应你看到的默认512字节。 - bss段(8字节):这个段专门存放未初始化的全局变量、静态变量,以及初始化为0的全局/静态变量(这类变量不需要在可执行文件中存储初始值,操作系统加载程序时会自动将bss段的所有内存清零)。你看到的初始8字节,是编译器或运行时库默认添加的辅助变量,比如栈保护相关的临时变量、全局对象初始化的占位变量等。
内容的提问来源于stack exchange,提问作者DJEBARRA RABAH ABDERRAZAK
相关产品推荐
相关产品推荐

