1、内存对齐的来源
计算机的机器字长表示计算机一次读取内存所能读取的字节数,常见的32位操作系统机器字长4字节,而64位操作系统机器字长8字节,以86位操作系统为例,如果不int类型的对齐字长设置为1字节,那么就有可能把int类型的变量存放到在6号到9号内存单元中,使得cpu在读取内存的时候需要两次I/O才能得到完整数据。
2、内存对齐的规则
- 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。
- 结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
- 指定对齐值:#pragma pack (value)时的指定对齐值value。处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度。和cpu数据总线的位数有关, 64位地址总线,存取粒度位8字节,就应该在程序中设置pragma pack(8)
- 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。
内存对齐要求变量的起始地址和占用的内存大小都是对齐值的倍数,对于结构体类型,里面的数据要做到对齐,结构体自身也要做到对齐!之所以结构体还要做到自身对齐,是为了方便结构体数组类型的存取
举例:
struct B{
char b;
int a;
short c;
};
char b 占用0号内存单元 而1,2,3号内存单元空闲;
int a 占用 4,5,6,7号内存单元
short c占用8,9号内存单元
目前占用10个内存单元,B本身的对齐值为 min{自身对齐值,当前指定的pack值}。自身的对齐值为成员中自身对齐值最大的那个值。也就是min{int的对齐值,pack值}=4, 所以10个单元要向上圆整成12,所以B的地址应该是12的倍数。