CPU在读取数据时会一次读取好几个字节,比如第一次读取0x00~0x03四个字节处理,第二次读取0x04~0x07四个字节处理,而不巧的是一个int型数据刚好存储于0x02~0x05这一片连续区域,那么为了读取这个int数据,CPU不得不读取两次内存再分别取高低字节进行拼凑才能够得到该数据,效率很低。
所以引入了数据对齐这么一个办法,首先了解一下自身对齐值、指定对齐指、有效对齐值的概念。
1. 基本数据类型的自身对齐值:就是对基本数据类型sizeof()后得到的值,记住:char-1Byte,short-2Byte,int-4Byte,float-4Byte,long-4Byte,long long-8Byte,double-8Byte。
2.结构体或者类的自身对齐值:就是其数据成员中sizeof()最大那个的值。
3.数组的自身对齐值:数组元素类型的大小,eg: int a[20]; a的自身对齐值为4Byte。
4.指定对齐值:#pragma pack (value),其中value的值就是指定的对齐值大小。
5.有效对齐值:将自身对齐值与指定对齐值进行比较后,较小的那个即为有效对齐值。
注意:有效对齐值才是我们在数据对齐时要使用的,自身对齐值及指定对期指的作用仅仅是比较得到有效对齐值。有效对齐值N表示该数据的存储起始地址%N=0。
再来了解数据对齐的基本规则:
1.数据或结构体、类中的数据成员的存储起始地址为有效对齐值N的倍数。
2.结构体或类或联合体最终的大小应为有效对齐值N的倍数(圆整)。
最后贴1个程序供自己实战一下,这个程序来自博客http://www.cnblogs.com/bakari/archive/2012/08/27/2658956.html
struct Practice2
{
struct T1
{
char _cA;
int _iB;
float _fC;
} _objX;
int _iD;
char _iE;
};
1、 求出此结构体在默认情况下的大小,并将其内存布局通过图文并茂的方式描述清楚。
2、 若在此结构体上之前加入#pragma pack(4),之后加上#pragma pack(),那么此时,其大小又为多少?
解:(1)0x00~0x11存T1,0x12~0x15存_iD,0x16存_iE,0x17~0x19位packing(圆整)。占20字节
(2)0x00~0x11存T1,0x12~0x15存_iD,0x16存_iE,0x17~0x19位packing(圆整)。占20字节
好像是一样的答案,哈哈~~完结撒花。。