结构体字节偏移两条准则:
1、每个成员的偏移位置是自身类型大小的整数倍;
2、结构体总大小是成员中最大类型大小的整数倍。
以下代码在32位机器xp系统下用vs2010测试
例如
class test
{
char x1;
char x2;
short x3;
float x4;
};//大小为8B
x1偏移0,当前大小1;
x2偏移为1的整数倍1,当前大小2;
x3偏移为2的整数倍2,当前大小4;
x4偏移为4的整数倍当前大小为8;
结构体大小为4的整数倍8B。
class test1
{
char x1;
short x2;
float x3;
char x4;
};//大小为12B
x1偏移0,当前大小1;
x2偏移为2(short大小)的整数倍2,x2与x1之间补齐1B,当前大小4;
x3偏移为4(int大小)的整数倍4,当前大小8;
x4偏移为1的整数倍当前大小为9;
结构体大小为4的整数倍,要补齐3B大小为12B。
以下可用同样规则计算
class test2
{
char x1;
float x2;
char x3;
short x4;
};//大小为12B
class test3
{
char x1;
float x2;
char x3;
};//大小为12B
int main()
{
int a = sizeof(test);
int b = sizeof(test1);
int c = sizeof(test2);
int d = sizeof(test3);
return 0;
}
如果在结构体定义之间加上宏定义
#pragma pack(n) //希望编译器按n个字节对齐
struct{...};
#pragma pack()//回复默认字节数对齐
使用这个宏定义后,原先的两条准则有些变化:
1、原先遵循每个成员自身对齐,即偏移是自身大小的倍数,首个成员偏移为0,现在变为每个成员按自身大小与n比较后,小的数的倍数进行偏移,如果n大于最大成员大小,则不起作用
2、结构体大小为n与最大成员大小比较后,小的数值的倍数。
测试
#pragma pack(1)
//#pragma pack(2)
//#pragma pack(4)
//#pragma pack(8)
//#pragma pack(16)
class test
{
char x1;
char x2;
double x3;
short x4;
float x5;
};
#pragma pack()
int main()
{
int a = sizeof(test);
return 0;
}
n(只能取2的a次方,其他值不确定规则)为1、2、4、8、16时,sizeof结果分别为16、16、20、24、24。
以上内容主要参考自博客 http://www.cppblog.com/Tauruser/archive/2007/02/28/19049.html