欢迎光临散文网 会员登陆 & 注册

C语言 sizeof计算结构体大小

2022-08-04 11:06 作者:GXTon_阿通  | 我要投稿

通常提到sizeof()就会想到烦人的:

关于sizeof()和strlen()的区别,有一大堆.

这里网上资料比较全,暂且放一放.

这一节介绍sizeof计算结构体大小:

为什么会是6呢?

大家都知道结构体在计算机中是按照定义时的顺序依次存储在连续的内存空间,
但是结构体的大小并不是简单相加,
需要考虑地址对齐问题。

结构体大小计算方法是,最后一个成员的偏移量加上其大小。
想象一个长条的缓存中,比如注射器,偏移量就有点像缓存中的活塞位置.
最后一个成员的偏移量,就是之前的成员所占内存和.加上最后一个成员的大小.

1,偏移量的计算也需要技巧,
需要满足:是成员大小的整数倍.

2,最后结构体的大小必须是所有成员的整数倍.

如果不满足上面两条,就需要对大小进行即时调整.使其满足上面条件.

比如上面例子中:

从a开始算,如果st结构体中只有a,那么st结构体的大小就是:

到a的偏移量0 + a的大小1 =1个字节.

如果st结构体中有a,b两个变量就是:

到b的偏移量,即(a占用的1)  + b的大小2  = 3个字节   (这里是错的 )

b的偏移量本来应该是1,但是,不满足前面的约束条件:
b的偏移量必须是b的整数倍,但是现在不满足了,1不是2的整数倍.所以需要调整偏移量.
那么b的偏移量就是从1->2,这样就可以了.
所以,到b处结构体st占用:
到b的偏移量(调整后占2)+b的大小(2) = 4个字节. (这里正确)

现在st有三个变量,a,b,c,所以还需要计算c.
到c处的偏移量是4,c占1,(此处是满足的,偏移量是成员的整数倍,即4是1的整数倍).

那么接着向下计算,

结构体st的大小:
到c的偏移量(4)+c的大小(1) = 5个字节.(这里是错的 )
但是这里是错的.因为5不满足上面的第二个条件,结构体的大小不是成员的整数倍.
5不是b(占2)的整数倍,所以,要调整结构体大小,让他满足.
所以从5调整到了6就可以了.

到c的偏移量(4)+c的大小(1) = 5个字节(调整到6).  (这里是正确的)
所以最终结果是6

编译器提供了一种字节对齐的方式

#pragma pack(1)  // 指定对齐
#pragma pack()    // 取消指定对齐
这两个通常是成对出现,放在结构体前后,用于偏移量的调整.

比如还是上面的例子,加入指定对齐之后:(结构体大小由原来的6变成了4.)

之所以由原来的6变成了4,
是因为#pragma pack(1)的作用,
它是为了让每个成员存储的起始位置发生变化.
比如上面没有加#pragma pack(1)之前.
计算结构体a,b占用大小时,b必须距离a 2个字节.
但是如果加了#pragma pack(1),因为传入参数是1,那么b既可以紧贴着a开始存储了.不用再考虑条件1中,偏移量是成员大小的整倍数了.

C语言 sizeof计算结构体大小的评论 (共 条)

分享到微博请遵守国家法律