如何计算结构体的大小

本文详细介绍了内存对齐的规则,包括结构体的首地址、成员偏移量和总大小的约束。同时解释了不同平台的内存访问差异可能导致的结构体大小不一致问题。还提到了预处理指令`#pragma pack()`用于调整对齐值。为了节省空间,建议将占用字节少的成员放在结构体前面。此外,文章提供了一个宏定义`OFFSET_OF`用于计算结构体成员的偏移量,帮助理解和优化结构体设计。
摘要由CSDN通过智能技术生成

计算结构体大小的三条规则:

  1. 结构体变量的首地址必须是“结构体最大成员变量所占字节数的整数倍”
  2. 结构体变量的成员的偏移量必须是该成员变量所占字节数的整数倍
  3. 结构体变量的总大小必须是最大结构体成员变量所占字节数的整数倍

字节对齐问题:

  1. 内存的基本变量是字节,理论上说是可以从任何地址访问内存,但实际上不是,CPU访问内存是以2、4或8 的倍数来读取字节块的,因此就会对一些基本类型的地址做出一些限制,既

他们的内存地址必须是2、4或者8的倍数,这就是内存对齐

2.有些平台是从偶数位开始读,有的则是奇数位
3.由于不同的平台读取的方式可能不同,相同的结构在不同的平台上的大小也不一样,所以在无意识的情况下,不同平台的数据相互传递有可能会产生严重的后果。

指令对齐值
预处理指令#pragma pack()可以改变默认对齐数,可改为1、2、4、8、16等。
vs的默认对齐数是8,gcc 是4.

总结

1.结构体的首地址=MIN{“结构体最大基本数据类型所占字节数”,指定对齐值}大小的整数倍。
2.结构体每个成员相对于结构体首地址的偏移量=MIN{基本数据类型成员,指定对齐方式}大小的整数倍
3.结构体变量的总大小={“结构体最大基本数据类型所占字节数”,制定对齐方式}大小的整数倍。

在设计结构体时既要满足对齐又要节省空间,如何做到?

设计的时候将所占字节数少的成员放到前面,所占字节数大成员放到后面,这样就减少了因为字节对齐而浪费掉的空间。

不定义结构体变量如何计算结构体成员的相对偏移量

((struct node_t *)0)->c

上述代码应该比较好理解,由于我们知道结构体的内存地址编号为0,所以我们就可以直接通过内存地址的方式来访问该结构体的成员变量,相应的代码的含义就是 获取内存地址编号为0的结构体struct node_t的成员变量c。

注:此处只是利用了编译器的特性来计算结构体偏移,并未对内存地址0有任何操作,有些同学对此可能还有些疑问,详细的了解该问题可参考关于c语言结构体成员变量访问方式的一点思考。

此时,我们的偏移求法就消除了struct node_t node这个自定义变量,直接一行代码解决,:

(unsigned long)(&(((struct node_t *)0)->c))

这里我们将上面的代码功能定义为一个宏,该宏的作用是用来计算某结构体内成员变量的偏移:

#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member))

使用上面的宏,就可以直接得到成员变量c在结构体struct node_t中的偏移为:

OFFSET_OF(struct node_t, c)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值