利用sizeof计算struct的大小的时候,要考虑内存对齐问题!看了很多文章总结起来有如下原则:
其默认原则如下:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
利用这个足以计算大多数情况!但是如果使用:#pragma pack(n)来设定变量以n字节对齐方式的话则需要满足以下原则:
1) n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏 移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
2) 结构的总大小也有个约束条 件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;
我在xcode里定义一个结构体:
struct s1{
char a;
double b;
int c;
char d;
};
然后sizeof(s1)! 结果却是20.。。。。。当时我就蒙了!
如果按默认原则!
a的偏移量为:0
b为:8 (a的长度补足为8,为b的整数倍)
c为:16
d为:20 (struct的整体长度应该为8的整数倍,所以d补足后为4)
总长度应该是24
自然而然我就想到可能是编译器默认#pragma pack(4)!
b的长度大于4所以a就补足为4了!整个struct就为20了!
于是我改变#pragma pack(16):
#pragma pack(push)
#pragma pack(16)
struct s1{
char a;
double b;
int c;
char d;
};
#pragma pack(pop)
结果:还是为20。。。所以这就不能理解了!!!理论上应该都是按默认原则计算!但是结果却还是20.。。。
先mark以后再看。。。