字节对齐
字节(Byte)是计算机信息技术用于计量存储容量和传输容量的一种计量单位,一个字节等于8位二进制数,在UTF-8编码中,一个英文字符等于一个字节。字节按照一定规则在空间上排列就是字节对齐。
一 作用和原因
由于各个硬件平台对存储空间的处理有很大的不同。一些平台对某些特定数据类型的数据只能从某些特定的地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程就必须保证字节对齐。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据进行对齐,会在存取效率上带来损失。比如有些平台每次都是从偶地址开始,如果一个int型(假设为32位操作系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果进行拼凑才能得到该32bit数据。
二 概念和对齐规则
1 概念
(1) 数据类型的自身对齐值:对于char型数据,其自身对齐值为1,对于short型为2即其本身的数据类型大小。
(2) 结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值
(3) 制定对齐值:#pragma pack(value)时的制定对齐值value
(4) 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个。
2 对齐规则
有效对齐值N是最终用来决定数据存放地址的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的“存放起始地址%N=0”。而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整。
三 对齐方式
程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉默认的对齐方式,自己可以设定变量的对齐方式。
编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。N字节就是说变量存放的起始地址的偏移量有两种情况:如果n大于等于该变量所占用的字节数,那么偏移量满足默认的对齐方式;如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
举例说明如下:
#pragma pack(8)
struct test
{
char m1;
double m4;
int m3;
};
sizeof(test)=16
其内存布局如下所示:
如果换成#pragma pack(8)的话那么sizeof(test)=24
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/lqlblog/article/details/46882801