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

L2中,第二个成员的偏移量是int,4的倍数,所以要填充3个字节+1个char,第三个成员的偏移量是char,1的倍数,要偏移出 填充3个字节 + 1个char + 1个int 一共8字节。目前总大小是9,9不是4的倍数,需要填充3个字节,最后总大小为12。

L3大小为8,大家可以自己计算一下。

浙公网安备 33010602011771号