内存对齐相关编译预处理命令
#pragma pack(x):该指令设置的值记为x,不进行设置时,x默认为8,可覆盖定义,即执行
#pragma pack(1)
#pragma pack()
x先设置为1,然后设置为默认值8
内存对齐过程
假设当前头文件定义了一个结构体(struct、class和union都遵循内存对齐),由char、int、double各一个组成(顺序很重要),设置了x=4
,则:
- 结构体中占用空间最大的成员double的字节数与x作比较,取小值为n,则n=4
- n与结构体中每个成员的字节数作比较,取小值得到数组m[i],如下:
#pragma pack(4) struct Test { char ch; // m[0] = sizeof(char) > n ? n : sizeof(char) = 1 int num; // m[1] = sizeof(int) > n ? n : sizeof(int) = 4 double fnum; // m[2] = sizeof(double) > n ? n : sizeof(double) = 4 };
- 根据结构体中每个成员的字节数进行空间分配,但是每个成员的起始地址,减去结构体的起始地址,得到的差值,需要为当前m[i]的整数倍,如下:
- 最后,结构体所占的字节数需要为n的整数倍,16/4=4,即结构体大小为16字节,若不足以整除n,则扩充结构体所占空间
示例
#pragma pack()
class Test2 {
char ch; // m[0] = sizeof(char) > n ? n : sizeof(char) = 1
double fnum; // m[1] = sizeof(double) > n ? n : sizeof(double) = 8
short snum; // m[2] = sizeof(short) > n ? n : sizeof(short) = 2
};
- n=8
- 如上图注释
- 内存排布如下,类大小为24字节
注意:当n=1时,不再有内存对齐的限制,直接将每个元素加起来即可得到结构体大小。