sizeof 结构体
- 格式:docx
- 大小:36.15 KB
- 文档页数:3
(转)结构体的sizeof的问题
(2008-04-17 18:28:23)
转载
标签: it 分类: 技术文章
在看我写的这篇资料以前,大家要明白结构体的字节对齐是怎么回事。不明白的到网上自
己找,弄懂了再来看我这篇文章。
首先要确定所求结构体的最大对齐字节边界数(也就是结构体的对齐字节边界数)。怎么样
来求一个结构体的最大对齐字节边界数呢?
很简单,先要知道结构体内成员的对齐字节边界数。设编译器设定的最大对齐字节边界数为
n,对于结构体中的某一成员member,它相对于结构首地址的实际字节对齐数目X应该满
足以下规则:
X = min(n,sizeof(member))
例如:
struct t0
{
chara; //在字节边界上对齐
int b[8]; //在4字节边界上对齐(能整除4的地址)
char c[9]; //在字节边界上对齐
double d[9]; //在8字节边界上对齐(能整除8的地址)
};
这个结构体内成员的最大对齐边界数是8,那么这个结构体的对齐字节边界数就为8。
弄清楚了上面这个概念,
如果是下面的结构体我想大家都知道怎样求它的大小。
struct sample //结构体的对齐字节边界数为4(因为结构体内成员的
{ // 最大对齐边界数sizeof(int)<编译器默认的8)
char a; //偏移=0
int b[8]; //偏移=4,填充了3个
char c[9]; //偏移=4+4*8=36,能整除4不用填充
};
那么sizeof(sample)=48(因为36+9=45,结构体的对齐字节边界数为4,而45不能整除4,
所以要填充3个到48)。
现在回来我们看看如何求结构体t0的sizeof数值。
struct t0
{
char a; //在字节边界上对齐
int b[8]; //在4字节边界上对齐(能整除4的地址)
char c[9]; //在字节边界上对齐
double d[9]; //在8字节边界上对齐(能整除8的地址)
};
这里的结构体的最大对齐字节数为8。那大家就想了
a的偏移为0
b的偏移为8,填充了7个
c的偏移为8+4*8=40
d的偏移为56(40+9=49,填充7个到56)
sizeof(t0)=128 (56+8*9=128)结果为128,实际上这样就错了!!
真正的过程是这样的
a的偏移为0
b的偏移为4,填充了3个(因为b是int型,所以这里要整除的是4不是8)
c的偏移为4+4*8=36
d的偏移为48(36+9=45填充了3个到48)d是double型,这里要整除的是8,不是4
sizeof(t0)=120 (48+8*9=120)结果为120。
这样的话就有个结论了:
结构体内一个成员的偏移要能整除它的对齐字节边界数。
结构体的sizeof的值要能整除这个结构体的对齐字节边界数。
得出这样一个公式:
结构体用t表示,结构体最后一个成员用lastmember表示
sizeof(t)= lastmember的偏移 + lastmember的大小 + 填充的数值
有了这个结论,我们再看看下面的例子
struct t1 //结构体的对齐字节边界数为8
{
char a; //a的偏移为0
int b[9]; //b的偏移为4
char c[9]; //c的偏移为40(4+4*9=40)
double d; //d的偏移为56(40+9=49填充7个到56)
char e[9]; //e的偏移为64(56+8=64)
int f[7]; //f的偏移为76(64+9=73填充3个到76)
char g[9]; //g的偏移为104(76+4*7=104)
char h[3]; //h的偏移为113(104+9=113)
char i[5]; //i的偏移为116(113+3=116)
};
结果sizeof(t1)=128 (116+5=121填充7个到128,128能整除8)
如果一个结构体内有另一个结构体声明的变量成员时,这个成员的对齐字节边界数就是它的
结构体的对齐字节边界数;这个成员的大小,就是它的结构体的sizeof的值。
例如
struct t0{
char a;
int b[8];
char c[9];
double d[9];
};
前面我们分析过sizeof(t0)=120,它的对齐字节边界数为8。
struct t2{ //结构体的对齐字节边界数为8
char a; //a的偏移值为0
int b[9]; //b的偏移值为4
char c[9]; //c的偏移值为40(4+4*9=40)
double d; //d的偏移值为56(40+9=49填充7个到56)
char e[9]; //e的偏移值为64(56+8=64)
int f[7]; //f的偏移值为76(64+9=73填充3到76)
char g[9]; //g的偏移值为104(76+4*7=104)
char h[3]; //h的偏移值为113(104+9=113)
struct t0 y; //y的偏移值为120(113+3=116填充4个到120)
char i[5]; //i的偏移值为240(120+120=240)
};
结果sizeof(t2)=248 (240+5=245填充3个到248,248能整除8)
不知道通过这几个例子的讲解你明白没有?以上都是我自己调试总结出来的,如果什么不对
的地方,欢迎大家批评指导