一、问题?
在进入正题之前首先看一下下面的一个简单例子,对于C++的这样两个结构体:
struct SizeLength1 struct SizeLength2
{ {
int a; char b;
char b; int a;
short c; short c;
}; };
这两个结构体一模一样,只是顺序变了一下。对于这两个结构体我们对他们的大小进行一下计算。
int size1 = sizeof(SizeLength1);
int size2 = sizeof(SizeLength2);
在window 32位下运行结果发现:size1 = 8, size2 = 12。由此可以看出虽然两个结构体的元素相同,但是顺序不一样,结构体所占的字节数也不一样,这就引发出我们下面需要讨论的问题了:字节对齐。
二、为什么需要字节对齐?
为什么需要字节对齐呢?原因就是为了加快计算机的计算速度,比如window 32位的系统,考虑到计算机的指令存取周期,每次读取4字节,我们按照四字节对齐就加快的数据的存取速度,否则就得多花指令周期。字节对齐原则:结构体默认的字节对齐一般满足三个准则:
(1)结构体变量的首地址能够被其最宽的基本类型成员所整除。
(2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员自身大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding)。
(3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
三、指定字节对齐
指定字节对齐,意思是指使用了宏 #pragma pack(n)来指定的对齐值(n = 1, 2, 4...)。
例子:
#pragma pack(push) // 压栈保存
#pragma pack(1) // 设置1字节对齐
struc SizeLength
{
char b;
int a;
short c;
};
#pragma pack(pop) // 恢复先前设置
现在我们在对这个结构体进行大小计算:size3 = sizeof(SizeLength); size3 = 7, 现在我们按照1字节对齐方式进行排列。因此我们计算的结构体大小,实际上就是结构体每个元素的大小的和。
除此设置对齐以外,还有 __attribute__ 方式可以设置对齐方式。具体方法请参考:
http://blog.chinaunix.net/uid-21830881-id-1813965.html
http://blog.163.com/tyw_andy/blog/static/11679021200910635047652/