NoFear

导航

深入理解字节对齐

Posted on 2012-08-12 12:05  Fear_Hao  阅读(377)  评论(0编辑  收藏  举报
之前一直把内存对齐弄错了,参考了下面两篇文章后,试着简单归纳下内存对齐规则
 
 
内存对齐主要有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]
}; //20min(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]
};  //49min(pack,sizeof(dounle)=8对齐=56