结构体对齐:
什么是对齐,以及为什么要对齐?
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。
网上其实说的蛮多,我把我自己理解的写下来。
三个规则
第一步算出实际占的大小。32位机器,int 占4 位,char 1位,short 占2位,等等
第二步,匹配大小,前面所占用的字节的个数必须调整为下一个类型的整数倍
第三部:最终所占用的大小必须调整为最大类型的整数倍。
我主要以举列子来说明:
struct A
{
int a;
char b;
short c;
};
第一步:int 占4个字节长度,char 占1个字节长度,short 占2个字节长度。很多人会以为sizeof(A)=7;这是错误的哦。
第二部:int a占四个,是char 的整数倍。所以不用补齐, int +char =5 ,而short 是2,前面需要补齐到6. 6+2=8.所以sizeof(A)=8;
第三部:8是4的整数倍,所以sizeof(A)=8;
struct B
{
char b;
int a;
short c;
};
那这个会是多少呢?
第一步还是一样的。
第二部:char b 占一位,但是int a 占4位,这样,char b 就要补齐到4 的整数倍。 所以char b,int a 就共占用8 个字节了。short 2个。
第三部: 目前是10个。但是最大的是4.所以要补齐为4 的整数倍。 所以sizeof(B)=12。
#progma pack (2) /*指定按2字节对齐,等价于#pragma pack(push,2)*/
struct C
{
char b;
int a;
short c;
};
#progma pack () /*取消指定对齐,恢复缺省对齐,等价于#pragma pack(pop)*/
比2小的 按补齐到2对齐。大的按原计划。最后也不要补齐到int 的整数倍。
sizeof(C)值是8。
未完待续。。。