之前一直把内存对齐弄错了,参考了下面两篇文章后,试着简单归纳下内存对齐规则
内存对齐主要有2大步骤:成员对齐和结构对齐
成员对齐规则:结构体第一个成员从位移0开始存储 eg:int [0-3]
从第二个成员开始,都要从min(pack值,this member size)的整数倍的位移开始存储
eg: #pragma pack(2) int成员 min(2,sizeof(int))= 2 所以从2的整数倍开始[2,4,6,8,10 -----]
特别情况,假如成员也是结构体,按照其内部元素类型最大的位移开始存储
结构对齐规则:结构体大小确定后,要根据 #pragma pack( pack值) 进行比较,取结构体内最大的成员类型大小与数字之间小者, min(sizeof(bigest 成员, pack值 )
然后进行取整补齐, eg: #pragma pack(4), struct A = 15, 成员类型最大为个字节 , min(4,8) = 4; 15按4取整为16 ; 所以sizeof(A) = 16
#pragma pack(2)
struct A
{
double a ; //[0-7]
char b [5]; //[8-12]
int c ; // 补[13] min ( ,sizeof(int))的整数倍位移开始 [14-17]
short d ; //min (,sizeof(short)) 的整数倍开始 X9=18 [18-19]
// 结构大小为按 min(2,sizeof(double)=2 19按取整 = 20
// 内存布局
};
#pragma pack(8)
struct A
{
double a ; //[0-7]
char b [3]; //[8-10]
int c ; //[11]min (,sizeof(int)) 的整数倍位移开始 X4=12 [12-15]
short d ; //min (,sizeof(short)) 的整数倍开始 X8=16 [16-17]
// 结构大小为按 min(8,sizeof(double)=8 18按取整 =24
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
//a b c d 补齐 ---------
};
#pragma pack(4)
struct A
{
char a ; //[0]
double b ; //[4-11] 按 min(sizeof(double),pack) = 4 从的倍数开始
int c ; //[12-15]
}; //16按min(pack,sizeof(double)=4对齐=16
struct B
{
char d ; //[0]
A e ; //[4-19] 按min(sizeof(double),pack) = 4 从的倍数开始
int f [3]; //[20-31]
char g [5]; //[32-36]
}; //37按min(pack,sizeof(double)=4对齐 =40
#pragma pack(8)
struct A
{
char a ; //[0]
double b ; //[8-15] 按 min(sizeof(double),pack) = 8 从的倍数开始
int c ; //[16-19]
}; //20按min(pack,sizeof(dounle))=8对齐=24
struct B
{
char d ; //[0]
A e ; //[8-31] 按min(sizeof(double),pack) = 8 从的倍数开始
int f [3]; //[32-43]
char g [5]; //[44-48]
}; //49按min(pack,sizeof(dounle)=8对齐=56