鱼C论坛

 找回密码
 立即注册
查看: 318|回复: 3

[已解决]offsetof

[复制链接]
发表于 2023-9-28 08:50:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

  1. //定义在 <cstddef> 头文件中   #include <cstddef>
  2. struct MyStruct
  3. {
  4.         int a;
  5.         char b;
  6.         double c;
  7. };

  8. void CoffsetofDlg::OnBnClickedButton1()
  9. {
  10.         // TODO: 在此添加控件通知处理程序代码

  11.         size_t offsetA = offsetof(MyStruct, a);
  12.         /*
  13.         offsetof 是一个宏,用于获取结构体中特定成员的偏移量(offset)
  14.         第一个参数是结构体的名字,第二个参数是结构体成员的名字
  15.         返回结构体中成员的偏移量。偏移量是size_t类型的
  16.        

  17.         offsetA=0
  18.         */
  19.         size_t offsetB = offsetof(MyStruct, b);
  20.         //offsetB=4
  21.         size_t offsetC = offsetof(MyStruct, c);
  22.         //offsetC=8




  23. }
复制代码




我的问题:int是4个字节,char是1个字节,我认为c的偏移量是5,不应该是8     ?
最佳答案
2023-9-28 08:51:36
根据您提供的代码,结构体MyStruct的成员按照声明顺序存放在内存中,对齐方式可能会影响成员的偏移量计算。

默认情况下,对于大多数编译器,结构体成员的对齐方式是按照成员的自身大小对齐。在您的示例中,int占用4个字节,char占用1个字节,double占用8个字节。

根据默认的对齐方式,成员ab的对齐需满足其自身大小。所以,int占用4个字节,对齐后的偏移量为0;char占用1个字节,对齐后的偏移量为4。

而对于double,由于其大小为8个字节,某些编译器默认要求double的对齐方式为8个字节。因此,在结构体中,成员a之后会插入一些填充字节以满足对齐要求。

这就解释了为什么成员c的偏移量是8而不是5。在这种情况下,由于ab的对齐要求,编译器在a之后添加了3个填充字节,然后才将成员c放置在偏移量为8的位置。

因此,根据默认对齐方式计算得出的a的偏移量是0,b的偏移量是4,c的偏移量是8。请注意,在不同的编译器和编译选项下,对齐方式可能会有所不同。

如果您希望更精细地控制结构体成员的对齐方式,可以使用特定的对齐指令(如#pragma pack)来设置对齐规则。

球一个最佳答案谢谢啦!这对我非常重要!
11.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-28 08:50:55 | 显示全部楼层
在结构体中,每个成员的地址都是按照其类型的大小对齐的。在这个例子中,int类型是4个字节,char类型是1个字节,double类型是8个字节。因此,编译器在分配内存时会将char类型的成员b放在a之后,以保证a的地址是4的倍数,这样访问a时效率更高。因此,b的偏移量是4,而不是1。同样的,c的偏移量是8,因为它需要在a和b之后占用8个字节的空间。因此,正确的答案是offsetC=8。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-28 08:51:36 | 显示全部楼层    本楼为最佳答案   
根据您提供的代码,结构体MyStruct的成员按照声明顺序存放在内存中,对齐方式可能会影响成员的偏移量计算。

默认情况下,对于大多数编译器,结构体成员的对齐方式是按照成员的自身大小对齐。在您的示例中,int占用4个字节,char占用1个字节,double占用8个字节。

根据默认的对齐方式,成员ab的对齐需满足其自身大小。所以,int占用4个字节,对齐后的偏移量为0;char占用1个字节,对齐后的偏移量为4。

而对于double,由于其大小为8个字节,某些编译器默认要求double的对齐方式为8个字节。因此,在结构体中,成员a之后会插入一些填充字节以满足对齐要求。

这就解释了为什么成员c的偏移量是8而不是5。在这种情况下,由于ab的对齐要求,编译器在a之后添加了3个填充字节,然后才将成员c放置在偏移量为8的位置。

因此,根据默认对齐方式计算得出的a的偏移量是0,b的偏移量是4,c的偏移量是8。请注意,在不同的编译器和编译选项下,对齐方式可能会有所不同。

如果您希望更精细地控制结构体成员的对齐方式,可以使用特定的对齐指令(如#pragma pack)来设置对齐规则。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-28 10:56:48 | 显示全部楼层
__attribute__((packed)) 你值得拥有
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 17:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表