全局数组导致BSS段大小超出预期的原因咨询
未初始化全局变量替换为4元素int数组后BSS段大小异常增长的原因
问题重现
第一个示例代码:
int global_uninitialized_0; int global_uninitialized_1; int global_uninitialized_2;
编译后通过size工具查看,BSS段大小为16字节(3个int共12字节,符合基础段对齐规则)。
替换其中一个变量为4元素int数组后的代码:
int global_uninitialized_0; int global_uninitialized_1; int global_uninitialized_2[4];
编译后size工具显示BSS段大小变为48字节;但替换为3元素数组时,BSS段大小的增长符合预期。
原因分析
你的怀疑完全正确,核心就是内存对齐,但这里的对齐不是单个变量的基础对齐,而是两个规则的叠加作用:
- BSS段的整体对齐要求:几乎所有编译器和链接器都会将BSS段对齐到特定的内存边界(比如16字节、32字节或CPU缓存行大小),目的是提升内存访问效率。第一个示例中12字节的变量总大小被对齐到16字节,就是这个规则的体现。
- 数组类型的高对齐要求:当定义4元素
int数组(总大小16字节)时,部分平台的编译器会为这类数组设置更高的对齐要求(比如16字节对齐,而非单个int的4字节对齐)。此时链接器在布局BSS段内的变量时,必须满足这个更高的对齐标准:- 前两个
int共8字节,为了让数组起始地址符合16字节对齐要求,需要在第二个int后填充8字节的空白空间。 - 数组本身占16字节,此时已用空间为8+8+16=32字节。
- 如果你的平台要求BSS段的最终大小必须对齐到更大的边界(比如48字节,可能由链接脚本或架构默认规则指定),就会出现从16字节跳变到48字节的情况。
- 前两个
而替换为3元素数组时,总大小(2个int+3个int=20字节)只需要对齐到下一个基础段对齐边界(比如24字节),因此增长符合预期。
验证方式
可以通过以下操作确认对齐规则的影响:
- 使用
objdump -x或readelf -S命令查看目标文件的段信息,重点关注BSS段的Align(对齐要求)和Size(实际大小)字段。 - 调整编译器/链接器的对齐相关选项(比如
-falign-sections、-malign-data),观察BSS段大小的变化。
内容的提问来源于stack exchange,提问作者Franks
相关产品推荐
相关产品推荐

