Post

结构体的字节对齐

I. 基本规则

几个原则:

  1. 长度最长的基本数据类型的长度作为基本单位
  2. 以基本类型本身长度的整数倍为起点进行对齐
  3. 最终长度是基本单位的整数倍

比如:

1
2
3
4
5
struct A {
    bool a;
    int b;
};
cout << sizeof(A) << endl;  // => 8 字节

int b 最长,4 字节,bool a 在第一个 4 字节的开始位置:

1
2
| bool |      |      |      |     // => 4 字节
|            int            |     // => 4 字节

再比如:

1
2
3
4
5
struct A {
    bool a;
    long c;
};
cout << sizeof(A) << endl;  // => 16 字节

long c 最长,8 字节,bool a 在第一个 8 字节的开始位置,即 bool 的 0 倍的位置:

1
2
| bool |      |      |      |      |      |      |      |     // => 8 字节
|                         long                          |     // => 8 字节

再比如这个也是 16 字节:

1
2
3
4
5
6
struct A {
    bool a;
    int b;
    long c;
};
cout << sizeof(A) << endl;  // => 16 字节

long c 最长,8 字节,bool a 在第一个 8 字节的开始位置,即 bool 的 0 倍的位置,由于这里已经有变量了,int b 要往后到 int 的 4 字节的 1 倍的位置:

1
2
| bool |      |      |      |            int            |     // => 8 字节
|                         long                          |     // => 8 字节

II. 伪指令 #pragma pack(n)

可以使用伪指令指定内存对齐的方式:

比如:

1
2
3
4
5
6
7
#pragma pack(4)

struct A {
    bool a;
    long c;
};
cout << sizeof(A) << endl;  // => 12 字节

这里原本是 16 字节,但是指定按 4 字节对齐后,就是 12 字节了:

1
2
| bool |      |      |      |     // => 4 字节
|                          long                         |     // => 8 字节

但是 n 不能比结构体中最大的基本数据类型长度还长,那样的话,这个命令就无效了。

This post is licensed under CC BY 4.0 by the author.