内存对齐
C语言内存对齐详解:struct大小计算、#pragma pack与对齐规则。
1. 对齐规则
1.1 基本规则
- 成员对齐:每个成员的偏移量必须是
min(成员大小, 默认对齐数)的整数倍 - 结构体对齐:结构体总大小必须是最大成员对齐数的整数倍
- 默认对齐数:VS 为 8,GCC 无默认值(按成员大小对齐)
1.2 示例
struct A {
char a; // 1 字节,偏移 0
int b; // 4 字节,偏移 4(填充 3 字节)
short c; // 2 字节,偏移 8
};
// sizeof = 12(填充到 4 的倍数)
struct B {
int b; // 4 字节,偏移 0
short c; // 2 字节,偏移 4
char a; // 1 字节,偏移 6
};
// sizeof = 8(更紧凑)
2. #pragma pack
#pragma pack(push, 1) // 1 字节对齐
struct Packed {
char a; // 偏移 0
int b; // 偏移 1
short c; // 偏移 5
};
#pragma pack(pop)
// sizeof = 7
3. 对齐计算公式
4. 为什么要对齐
- CPU 访问对齐的内存更快(单次总线传输)
- 某些架构访问未对齐内存会触发异常
- 空间换时间的权衡