要进行内存对齐要先确定有效对齐值也叫对齐单位、偏移量才能进行计算具体可以分为下面3个部分1、有效对其值有效对齐值对齐单位是给定值#pragma pack(n) 与 结构体中最长数据类型长度两者中较小的那个。2、偏移量偏移量可以简单的理解为起始点到数据本身开始点之间的距离。具体为结构体第一个成员的偏移量是0起始点与数据本身开始点是同一个点以后每个成员相对于结构体首地址的偏移量都是 该成员大小与有效对齐值中较小那个 的整数倍如有需要编译器会在成员之间加上填充字节。3、计算总大小结构体的总大小为 有效对齐值 的整数倍如有需要编译器会在最末一个成员之后加上填充字节。下面给出几个例子以便于理解//32位系统#includestdio.h#pragmapack(4)struct{intE;charT1;charT2;}L1;struct{charT1;intE;charT2;}L2;struct{charT1;charT2;intE;}L3;intmain(){printf(%d\n,sizeof(L1));// 输出8printf(%d\n,sizeof(L2));// 输出12printf(%d\n,sizeof(L3));// 输出8return0;}根据上面介绍的规则来分析一下L1、L2、L3的size大小下面以为L1为例。1先确定L1的有效对齐值#pragma pack(4)设置大小为4L1结构体中最长数据类型长度是4int型有效对齐值为4。2逐个计算偏移量与数据大小第一个偏移量是0int类型大小是4目前总大小为4。第二个成员是char类型它与有效对齐值4相比char是较小的偏移量是char的整数倍char的size是1即1的整数倍只需要把前面int类型偏移出来就行。因此目前总大小为5。第三个成员也是char偏移量是char的整数倍只需要把前面intchar的大小偏移出来即可所以总大小是6。3结构体总大小是有效对其值的整数倍因此L1的大小需要是4的倍数6不是4的倍数所以要补充2个字节总大小为8字节。L2中第二个成员的偏移量是int4的倍数所以要填充3个字节1个char第三个成员的偏移量是char1的倍数要偏移出 填充3个字节 1个char 1个int 一共8字节。目前总大小是99不是4的倍数需要填充3个字节最后总大小为12。L3大小为8大家可以自己计算一下。
内存对齐规则
要进行内存对齐要先确定有效对齐值也叫对齐单位、偏移量才能进行计算具体可以分为下面3个部分1、有效对其值有效对齐值对齐单位是给定值#pragma pack(n) 与 结构体中最长数据类型长度两者中较小的那个。2、偏移量偏移量可以简单的理解为起始点到数据本身开始点之间的距离。具体为结构体第一个成员的偏移量是0起始点与数据本身开始点是同一个点以后每个成员相对于结构体首地址的偏移量都是 该成员大小与有效对齐值中较小那个 的整数倍如有需要编译器会在成员之间加上填充字节。3、计算总大小结构体的总大小为 有效对齐值 的整数倍如有需要编译器会在最末一个成员之后加上填充字节。下面给出几个例子以便于理解//32位系统#includestdio.h#pragmapack(4)struct{intE;charT1;charT2;}L1;struct{charT1;intE;charT2;}L2;struct{charT1;charT2;intE;}L3;intmain(){printf(%d\n,sizeof(L1));// 输出8printf(%d\n,sizeof(L2));// 输出12printf(%d\n,sizeof(L3));// 输出8return0;}根据上面介绍的规则来分析一下L1、L2、L3的size大小下面以为L1为例。1先确定L1的有效对齐值#pragma pack(4)设置大小为4L1结构体中最长数据类型长度是4int型有效对齐值为4。2逐个计算偏移量与数据大小第一个偏移量是0int类型大小是4目前总大小为4。第二个成员是char类型它与有效对齐值4相比char是较小的偏移量是char的整数倍char的size是1即1的整数倍只需要把前面int类型偏移出来就行。因此目前总大小为5。第三个成员也是char偏移量是char的整数倍只需要把前面intchar的大小偏移出来即可所以总大小是6。3结构体总大小是有效对其值的整数倍因此L1的大小需要是4的倍数6不是4的倍数所以要补充2个字节总大小为8字节。L2中第二个成员的偏移量是int4的倍数所以要填充3个字节1个char第三个成员的偏移量是char1的倍数要偏移出 填充3个字节 1个char 1个int 一共8字节。目前总大小是99不是4的倍数需要填充3个字节最后总大小为12。L3大小为8大家可以自己计算一下。