转载请注明出处: http://blog.csdn.net/zhangyang0402/archive/2010/08/09/5799977.aspx
在结构体的定义中,经常遇到字节对齐的问题,尤其是在网络程序中。
一、什么是字节对齐?
在计算一个结构体的sizeof值时,并不是简单了计算结构体各成员的大小的和,而应考虑到各成员间和整个结构体的字节对齐问题。
如
struct S
{
char ch;
int i;
short j;
};
sizeof(struct s)的结果并不是1+4+2=7,而是1+3+4+2+2=12, 其中的3和第二个2就是填充字节的大小。
二、为什么要字节对齐?
提高CPU读写内存的效率,从而提升系统性能。
三、默认对齐原则
默认的对齐原则为:
1) 结构体的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体成员相对结构体的偏移量必须是成员类型大小的整数倍,否则进行填充直至是整数倍;
3) 结构体的大小必须为最大基本类型成员的大小的整数倍,否则在最后一个成员后进行填充,直至是整数倍。
以前面的struct S结构体为例
成员ch,char型,偏移量为0,默认对齐大小为1;
成员i, int型,偏移量为1,默认对齐大小为4, 1 % 4 不等于0,则进行填充,这里需要填充3个字节(填充的是随机值)
成员j, short int型, 偏移量为8,默认对齐大小为2, 8 % 2 等于0。 但此时整个结构体大小为1+3+4+2=10,不是4的整数倍。所以,需要在j的后面填充2个字节。
四、更改默认对齐
#pragma pack(n) // 设置n个字节对齐
#pragma pack() //取消n个字节对齐
当使用pragma pack指定对齐字节大小,每个成员确定对齐大小时,取成员类型大小和指定对齐大小的较小值(若默认对齐大小被改变,则只须考虑按指定对齐字节对齐)。
测试1:
#pragma pack(2)
struct S
{
char ch;
int i;
short j;
};
#pragma pack()
则sizeof(struct S) = 1+1+4+2 = 8
测试2:
#pragma pack(2)
struct S
{
char ch;
int i;
};
#pragma pack()
则sizeof(struct S) = 1+1+4 = 6
五、策略
在定义结构体时,应注意字节对齐的问题,特别是在网络应用程序中。因此,定义结构体时,应按成员类型大小从小到的顺序定义,如果实在有填充字节,可将填充字节部分定义为reserved字段。