☰
C/C++的内存对齐
2026/10/7 8:19:30 网站建设 项目流程

内存对齐

内存对齐是 编译器自动安排结构体成员在内存中的存放位置,并且在成员之间、结构体末尾自动插入填充字节(padding),让每个成员的起始地址满足特定倍数要求

规则

  1. 第⼀个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对⻬到对⻬数(对⻬数 = 编译器默认的⼀个对⻬数与该成员⼤⼩的较⼩值)的整数倍的地址处。
  3. 如果结构体里面嵌套另一个结构体,内部结构体的对齐单位 = 内部结构体最大基础成员的大小。
  4. 结构体最后的总大小,必须是整个结构体最大基础成员大小的整数倍。成员排完不够倍数,在结构体末尾补 padding。
  5. 在 vs 中,默认对齐数是 8。

例子

以下例子在 vs 2022 编译器下执行:

structA{inta;charb;charc;};structB{charb;inta;charc;};printf("%zu\n",sizeof(A));// 结果为 8printf("%zu\n",sizeof(B));// 结果为 12

结构体 A 和 B 拥有完全相同的成员变量,但是计算出来的内存大小却不同。
分析:

  • A 和 B 的成员变量类型为 int(4字节),char (1字节),4 > 1 ,故最大成员的大小为4字节;
  • vs 默认对齐数为 8 字节,8 > 4 ,故结构体的对齐数为4字节;
  • 结构体 A中,成员 a 为 int ,占用地址偏移量从 0 到 3,成员 b 为 char,占用地址偏移量 为 4,同理成员 c 为 5,为了符合对齐数 4字节的整数倍,结构体末尾补上 2字节,则整个结构体的偏移量为 0 到 7 共 8 字节;
// 示意图01234567a a a a b c \ \
  • 结构体 B中,成员 b 为 char ,占用地址偏移量为 0 ,成员 a 为 int,为了对⻬到对⻬数⼤⼩的整数倍的地址处,b 后面补上 3字节,则 a 占用地址偏移量 为 4 到 7,同理得成员 c 为 8,为了符合对齐数 4字节的整数倍,结构体末尾补上 3字节,则整个结构体的偏移量为 0 到 11 共 12 字节;
// 示意图01234567891011b \ \ \ a a a a c \ \ \

为什么要有内存对齐

内存对齐的出现是为了适配CPU的访问规则,提升内存读写效率。CPU访问内存不是单字节读取的,而是按照固定块(2/4/8 字节,叫访问粒度)读取。
比如CPU一次性读取 4字节时,如果我们没有内存对齐规则地去访问结构体:

structA{charb;inta;charc;};// 假设没有内存对齐的示意图01234567b a a a a c

这里成员 a 跨了两个内存块,CPU 就需要读两次内存,再拼接、裁剪,速度变慢。

内存对齐好处和坏处

  • 好处:CPU 读写更快,兼容更多硬件。
  • 坏处:填充字节 padding,结构体占用内存变大。
    内存对齐是空间换时间的典型例子。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询