首页 > 代码库 > 字节对齐与结构体大小

字节对齐与结构体大小

#pragma pack (n) /*指定按n字节对齐*/   不写这句默认n =8

设真正的对齐长度为m字节

如果n>结构体中数据类型(包括类类型)长度最大的数据类型长度,m = 结构体中最大数据类型长度

否则 m = n

总之,真正的对齐长度m为指定对齐长度n与结构体中最大类型长度中的较小值。


规则:

1. 结构体变量的首地址能够被m所整除;

2. 结构体每个成员相对于结构体首地址的偏移量都是m的整数倍,如有需要编译器会在成员之间加上填充字节;

3. 结构体的总大小为m的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。


举例:(摘自:http://pppboy.blog.163.com/blog/static/30203796201082494026399/)

很显然默认对齐方式会浪费很多空间,例如如下结构: 

struct student 
{ 
    char name[5]; 
    int num; 
    short score; 
}


本来只用了11bytes(5+4+2)的空间,但是由于int型默认4字节对齐,存放在地址能被4整除的起始位置,即:如果name[5]从0开始存放,它占5bytes,而num则从第8(偏移量)个字节开始存放。所以sizeof(student)=16。于是中间空出几个字节闲置着。但这样便于计算机快速读写数据,是一种以空间换取时间的方式。其数据对齐如下图:

|char|char|char|char| 
|char|----|----|----| 
|--------int--------| 
|--short--|----|----| 

如果我们将结构体中变量的顺序改变为: 

struct student 
{ 
    int num; 
    char name[5]; 
    short score; 
}


则,num从0开始存放,而name从第4(偏移量)个字节开始存放,连续5个字节,score从第10(偏移量)开始存放,故sizeof(student)=12。其数据对齐如下图:

|--------int--------| 
|char|char|char|char| 
|char|----|--short--| 

如果我们将结构体中变量的顺序再次改为为: 

struct student 
{ 
    int num; 
    short score; 
    char name[5]; 
}


则,sizeof(student)=12。其数据对齐如下图:

|--------int--------| 
|--short--|char|char| 
|char|char|char|----|