内存对齐规则

内存对齐规则

1.规则:

  • 数据成员的偏移量以min(pack(n),最大成员占用字节)的整数倍进行对齐。

2.其它说明

  1. 内存对齐,是指数据在内存中的存放位置必须是其对齐字节数(一个无符号整数,且必须是2的幂)的倍数。这样做可以提高数据访问的效率和性能。

  2. C++中,不同类型的数据有不同的默认对齐字节数,例如int为4,char为1,double为8等。如果数据是自定义类型(如类或结构体),则其正常对齐字节数等于其最大成员的对齐字节数。

  3. C中还可以使用#pragma pack(n)或__attribute__((aligned(n)))等指令来修改默认的对齐方式。C11还引入了alignof和alignas两个关键字来获取或设置数据的对齐字节数。

案例

请看下面的代码:

// 例1:默认对齐方式
struct A {
char a; // 占1字节,偏移0
int b; // 占4字节,偏移4(因为要对齐到4的倍数)
char c; // 占1字节,偏移8
}; // 结构体A的大小为12(因为要对齐到最大成员的倍数)

// 例2:使用#pragma pack(2)指令
#pragma pack(2) // 设置对齐字节数为2
struct B {
char a; // 占1字节,偏移0
int b; // 占4字节,偏移2(因为要对齐到2的倍数)
char c; // 占1字节,偏移6
}; // 结构体B的大小为8(因为要对齐到指定的倍数)
#pragma pack() // 恢复默认对齐方式

// 例3:使用__attribute__((aligned(8)))指令
struct C {
char a; // 占1字节,偏移0
int b __attribute__((aligned(8))); // 占4字节,偏移8(因为要对齐到8的倍数)
char c; // 占1字节,偏移12
}; // 结构体C的大小为16(因为要对齐到最大成员的倍数)

// 例4:使用C++11中的alignas关键字
struct D {
alignas(16) char a; // 占1字节,偏移0(但是占用16个空间)
int b; // 占4字节,偏移16(因为要对齐到16的倍数)
char c; // 占1字节,偏移20
}; // 结构体D的大小为32(因为要对齐到最大成员的倍数)

// 例5:含double的结构体
struct E {
int a;
double b;
char c;
}; // 结构体E的大小为24