【C_C++】根据结构体中的成员地址求结构体的地址


typedef struct {

    int a;

    int b;

    int member;

}type;

现在定义如下:

type  test;

type *ptest;

并且已经 test.member的地址为ptr, 即,ptr = &test.member,但是并不知道test 的地址,求test的地址ptest。

显然ptest = ptr – member在成员中的偏移(上述例子中为8)。但是偏移要怎么求?具体要怎么写?

 

下面请看经典代码中的写法:

 

ptest = container_of(ptr, type, member);

 

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({ 
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})


 

针对上面的定义,分析如下:

先看offsetof

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)的意义

 

((type *)0)为设计一个type类型的结构体,起始地址为0.

于是它的member就是((type *)0)->member;

member的地址 = 结构体((type *)0)的起始的地址 + member的偏移。

&((type *)0)->member = ((type *)0) + offset

于是,member在结构体中的偏移offset的计算方法如下:

offset = &((type *)0)->member - ((type *)0)

由于结构体起始地址为0,所以此结构体成员变量的偏移地址就等于其成员变量在结构体内的距离结构体开始部分的偏移量。

offset = &((type *)0)->member - ((type *)0) = &((type *)0)->member;

即:&((type *)0)->member就是取出其成员变量的偏移offset,#define offsetof将其转换为size_t类型。

 

再看container_of

const typeof( ((type *)0)->member ) *__mptr = (ptr);

 

typeof(((type *)0)->member)为取出member成员的变量类型。

再用其定义__mptr指针。ptr为指向该成员变量的指针。 __mptr为member数据类型的常量指针,其指向ptr所指向的变量处。

 

3,(type *)( (char *)__mptr - offsetof(type,member) )  

 

(char*)__mptr转换为字节型指针。

根据上面的分析ptest = ptr – member在成员中的偏移

要求的地址,假设为X,就有X = (char*)__mptr - offsetof(type,member)), 但此是X还是char *, 需要强制类型转换。

(type *)X = (type*)(char*)__mptr - offsetof(type,member));

于是type *ptest = (type *)X = (type*)(char*)__mptr - offsetof(type,member));


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值