container_of学习记录

container_of 主要用于解决

已知

  • 某个成员的地址: ptr
  • 该成员的名称:member;
  • 包含该成员的类型:struct container{…, member,…};

得到

  • 包含该成员的类型的实例的地址

简释如下:

#include<stdio.h>
#include <stddef.h>

/**< build in macro
 * #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)
 */
/**<
 * 1. 将任意地址强转为包含该成员的类型的指针:(type*)0xFFFFFFFF; (一般写(type*)0)
 * 2. 用得到的指针访问该成员: ((type*)0xFFFFFFFF)->member, 相当于得到该成员变量;
 * 3. 用typeof推断该成员变量的类型:typeof( ((type *)0xFFFFFFFF)->member );
 * 4. 定义该成员变量类型(第3步推断出的类型)的指针变量: __mptr;
 * ----------------------------------以上4步推断出成员的类型
 * 5. 该成员的地址赋值给__mptr;
 * 6. 该成员的地址减去该成员相对于包含该成员的类型的偏移:offsetof(type,member);得到
 * 包含该成员的类型的实例对象的首地址;
 * 7. 将该地址转为包含该成员的类型。OVER
 */
#define container_of(ptr, type, member) ({          \
        const typeof( ((type *)0xFFFFFFFF)->member ) *__mptr = (ptr); \
        (type *)( (char *)__mptr - offsetof(type,member) );})

struct test {
	int ma;
	int mb;
	int mc;
};

int main()
{
	struct test t;                       ///< 实例对象
	//const typeof(t.mb) *pmb = &(t.mb); ///< 已知成员mb的地址
	int *pmb = &(t.mb);                  ///< 已知成员mb的地址
	struct test *tp = container_of(pmb, struct test, mb); ///< 由该对象的成员地址得到实例对象的地址
	printf("object  addr: %p\n", &t);
	printf("container_of: %p\n", tp);

	return 0;
}

这里我们已知:类型test的实例对象t的成员mb的地址pmb,用container_of得到该实例对象t的首地址tp。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值