原则1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,之后每一个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。(即pack指定的值和成员自身比较,小的那个整数倍对齐)markdown
原则2:结构(或联合)的总体对齐规则:在数据成员完成各自对齐以后,结构(或联合)自己也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。(即pack指定的值和最大成员自身比较,小的那个整数倍对齐)网络
原则3:结构体做为成员:若是一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。数据结构
#pragma pack(2)
struct Struct1{
double a; //0-7
char b; //8
int c; //起始min(2,4)=2,因此从2的倍数开始 10 11 12 13
short d; //14 15
} structOne; //min(2,8)=2, 2的倍数 16
#pragma pack()
struct Struct2{
double a; //0-7
char b; //8
int c; //起始min(8,4)=4,因此从4的倍数开始 12 13 14 15
short d; //16 17
} structTwo; //min(8,8)=8, 8的倍数 24
复制代码
运行结果:大数据
能够看出此时structOne和structTwo,内部成员变量顺序彻底一致,指定了#pragma pack()以后sizeof获得的结果彻底不一样。spa
#pragma pack(show)
struct Struct1{
double a; //0-7
char b; //8
int c; //起始min(8,4)=4,因此从4的倍数开始 12 13 14 15
short d; //16 17
} structOne; //min(8,8)=8, 8的倍数 24;
struct Struct2{
double a; //0-7
int c; //起始min(8,4)=4,因此从4的倍数开始 8 9 10 11
char b; //12
short d; //14 15
} structTwo; //min(8,8)=8, 8的倍数 16
复制代码
运行结果code
能够看出结构体成员顺序不一样,虽然pragma pack相同,sizeof获得的字节数不一样。orm
这是由于结构体总体对齐,是按照最大成员变量int长度的和pack默认的8中最小比较是4,4的最小倍数是20;内存
结构体的对齐显示成员对齐,而后是结构体的总体对齐,根据内存对齐原则,来对齐内存。编译器
1:根据数据成员对齐:it
根据#pragma pack(x) 根据x这个数值和依次排列的数据成员自身的长度的数作比较,那个小用哪一个。
这样就排出来了每个数据所占的地址及位置。是依次排列,可是不是依次挨着排列,要排列的数据要看本身数据成员自身长度的数和x哪一个更小,假设自身数据长度为4,x为8,则再看本身要依次排列的地址是否是4的倍数,若是不是,则自动延长地址到4的倍数处,再赋值。
2:数据结构对齐:
当上面那个对齐了每个数据成员后, 如今须要对数据结构总体长度对齐。找出数据结构成员中最大长度的数据的值z,跟x作对比,找到最小的那个,假设x为8,z为4,则总体数据结构长度应该是4的整数倍,不够自动补齐。
3:结构体做为成员
若是成员内有结构体,须要看结构体中最大的成员的长度h来作比较,是h的倍数。