如何正确使用container_of()获取结构体中的指针类型字段?
问题分析与解决
你的问题核心是混淆了结构体成员的地址和结构体成员的值,container_of() 的第一个参数必须是结构体成员的地址,而不是成员的值。
为什么两种写法都错?
第一种写法
container_of(&ptr, struct A, ptr):
这里的&ptr是函数参数ptr(栈上的局部变量)的地址,根本不是某个struct A实例中ptr成员的地址。虽然编译能过,但计算出来的结构体地址完全不对,因为你用了错误的基地址来计算偏移。第二种写法
container_of(ptr, struct A, ptr):ptr是int*类型(成员的值),而container_of()要求第一个参数是成员的地址(对应这里的类型是int**)。宏内部的类型检查会对比*(ptr)(也就是int类型)和((struct A*)0)->ptr(也就是int*类型),显然类型不匹配,所以触发编译错误。
正确用法
如果你确实需要通过 struct A 中的 ptr 成员来找到对应的结构体实例,你必须传入该成员的地址(即 int** 类型),而不是成员指向的地址。示例如下:
#include <stddef.h> // 必须包含offsetof的头文件 struct A { int *ptr; }; void some_func(int **ptr_member_addr) { // 传入的是struct A中ptr成员的地址 struct A *a = container_of(ptr_member_addr, struct A, ptr); } // 使用示例 int main() { int x = 10; struct A my_a = {.ptr = &x}; some_func(&my_a.ptr); // 传入成员的地址,而非成员的值 return 0; }
关键提醒
如果你的需求是通过某个int变量的地址找到指向它的struct A实例,那container_of()做不到——因为多个struct A的ptr成员都可以指向同一个int变量,不存在从int地址反向映射到结构体的机制。这种场景下你需要自己维护额外的映射关系(比如哈希表)。
内容的提问来源于stack exchange,提问作者k1r1t0
相关产品推荐
相关产品推荐

