1.看编译环境,确认默认对齐位数
32位编译器,默认最小对齐为4字节,64位编译器默认最小对齐为8字节,指针长度也是8字节;
注意:64位系统在编译器是32位时或者注释为32位时,默认对齐也为4字节。可用以下语句声明为4字节:
#pragma pack(4)
2.再确定最终对齐位数
在确定默认对齐位数后,找出结构体中最长字节的数据类型,比较最长数据类型和默认对齐位数,谁小,谁是最终对齐位数。
注意:最长字节的数据类型计算取其原始类型,比如,char a[3],在算最长数据类型时,其值为1。
3.长度计算
再加入新的长度时,需要计算已有长度时候能够整除新添加长度,不能整除需要填充空间进行偏移,直到能够整除,放入新的长度。最后完整长度需要能够整除最终对齐位数,不能整除则需要填充偏移。
例如:
#pragma pack(4)
struct Test
{
int Num;//4
int pcName;//8
short sDate;//10
char cha[2];//12
short sBa[4];//20
};
默认对齐位数为:4
最长数据类型长度为:4
最终对齐长度为:4
长度计数为:4(int)+ 4(int) + 2(short) +1* 2(char[2]) + 2*4(short[4]) = 20;
(每一项都能够整除所以不用偏移。注意2*4(short[4])整除计算时计算的是原型short。)
#pragma pack(4)
struct mC
{
char a[3];
int b;
char c;
short d[4];
};
默认对齐位数为:4
最长数据类型长度为:4
那么最终对齐长度为:4
长度计数为:3(char[3])+ 1(偏移) + 4(int ) + 1(char) +1(偏移) + 2*4(short[4]) + 2 (偏移) = 20;
(数据类型3(char[3])能够被已有长度0整除,不用偏移,目前已有长度3不能整除4(int ),偏移1位,目前已有长度4能够整除4(int ),目前已有长度8能够整除1(char),不偏移直接放入1(char),目前已有长度9不能整除2(short),偏移1位,目前已有长度10能够整除2(short[4]),放入8(short[4]),最终长度18不能够整除最终对齐长度4,偏移2位,最终长度为20)
#pragma pack(4)
struct mC
{
doule a;
char b;
};
默认对齐位数为:4
最长数据类型长度为:8
那么最终对齐长度为:4
长度计数为:8 + 1 + 3(偏移) = 12;
#pragma pack(4)
struct mC
{
char b[3];
};
默认对齐位数为:4
最长数据类型长度为:1
那么最终对齐长度为:1
长度计数为:1*3 = 3;
注意在32位编译器时指针长度为4字节,在64位编译器时是8字节。