结构体的成员不同的存放顺序,结构体的大小会有不同,这与结构体的对齐单位与结构体成员的偏移量有关
结构体对齐单位
结构体的对齐单位由下面3个数值的大小决定,且取其中的最小值,结构体的最终大小一定是对齐单位的正数倍
1、系统架构设置的默认单位:windows系统8字节对齐、32位linux系统 4字节对齐、64位linux系统4字节对齐
2、结构体成员最大类型
3、程序设定 #pragma pack(x)
结构体的偏移量
结构体的偏移量是结构体成员存放时成员的地址相对于结构体的起始地址偏移,偏移量的求值规则:
1> 相应成员类型大小的整数倍
2>如果被其他成员占用,不能放
3> 被两个成员夹住也不能放
4> 如果成员类型大小大于对齐单位,应该以对齐单位的整数倍求偏移量
// 假设程序运行在Windows上,系统架构设置的默认对齐单位为8字节
// 结构体成员的最大类型为int,对齐单位为4个字节
// 程序通过#pragma pack(x)设置的对齐单位为16字节
// 最终的对齐单位上述3个值的最小值,即4个字节
#pragma pack(16)
struct Test
{
char a;
int b;
short c;
}
/* 首先对齐单位为4
* 成员a偏移量:1 * 0 得结构体的首地址,结构体的第一个成员,首地址没有被占用
* 即第一个字节存放成a
* 成员b的偏移量:4 * 0,首地址已被占用,不能存放
* 4 * 1,另外起一个对齐单位,此时结构体的大小为两个对齐单位8
* 成员c的偏移量:2 * 0,首地址已被占用,不能存放
2 * 1 存放成员c,成员c会被第一行的a和第二行的夹住,所以不能存放,
* 为了不被夹住,c的最终偏移量为2 * 4,所以结构体的最终大小为3个对齐单位12
*/
内存布局为
为保证结构体的大小合理,应该先存放数据类型小的成员变量,如果结构体成员有数组,应该拆成若干个基础数据类型来计算。