使用container_of()宏获取容器结构体指针时出现编译错误的问题
问题解答:container_of编译错误的原因与修复
写法不可行的原因
container_of的核心作用是通过结构体成员的指针,反向获取整个结构体的指针,它要求第一个参数必须是指向结构体成员本身的指针,而不是指向成员所指向对象的指针。
看你的结构体定义:
struct a { int b; char *c; }; struct d { struct a *_a; // _a是struct d的成员,类型为struct a* int e; };
你传入的p是struct a*类型,指向的是一个struct a对象,但container_of需要的是指向struct d的_a成员的指针(也就是struct a**类型),两者类型完全不匹配,因此触发了编译阶段的断言错误。
解决方法
因为指针是单向关联的——struct d知道自己的_a指向哪个struct a,但struct a对象本身不知道被哪个struct d的_a指向,所以无法直接用container_of通过p反向找到struct d。有两种常用的解决思路:
方案1:给struct a添加反向指针
修改结构体定义,在struct a中新增一个指向struct d的指针,建立双向关联:
struct d; // 前向声明,避免编译报错 struct a { int b; char *c; struct d *owner; // 新增反向指针,指向包含当前struct a的struct d }; struct d { struct a *_a; int e; };
初始化时,需要同时设置双向关联:
struct a a_instance; struct d d_instance; d_instance._a = &a_instance; a_instance.owner = &d_instance;
之后就可以直接通过p->owner拿到对应的struct d指针,修改e成员:
p->owner->e = 100; // 示例修改值
方案2:维护映射表
如果不能修改struct a的定义,可以维护一个哈希表或链表,记录struct a*到struct d*的对应关系。
- 创建
struct d并让_a指向某个struct a时,把(&a_instance, &d_instance)的键值对存入映射表; - 需要通过
p查找对应的struct d时,直接在映射表中根据p查询即可。
额外说明
如果你的场景是持有指向struct d的_a成员的指针(比如有一个变量struct a** ptr_to__a = &d_instance._a),那container_of的用法是完全正确的:
struct d *d_ptr = container_of(ptr_to__a, struct d, _a); d_ptr->e = 100;
但这和你当前的场景完全不同,你现在的p是struct a*,并非指向struct d成员的指针。
内容的提问来源于stack exchange,提问作者Ratin Rahman
相关产品推荐
相关产品推荐

