## “container_of 技术” 是 C 语言低层技巧中的王者级工具,它的精髓在于:“从结构体中的成员指针,反推整个结构体的地址。”理科生网链接地址:https://www.lksr.net/2025/11/c-containerof.html{alertInfo}
由人工编写审核,非AI生成内容,请放心观看!
{getToc} $title={文章目录}
“container_of 技术” 是 C 语言低层技巧中的王者级工具,它的精髓在于:“从结构体中的成员指针,反推整个结构体的地址。”
C 语言低层技巧中的王者级工具:container_of 技巧
在 Linux 内核中广泛使用(几乎无处不在),比如链表、设备驱动、内核对象管理等。
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))这个宏 list_entry(ptr, type, member) 用于在 C 语言中从结构体成员的指针获取指向整个结构体的指针。下面是这个宏的逐步解释:
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))ptr: 结构体成员的指针。type: 结构体的类型(即member所属的结构体类型)。member: 结构体中的某个成员的名称。
让我们逐步分析宏中的每个部分:
&((type *)0)->member:(type *)0: 这表示一个type类型的空指针。通过将0强制转换为type *类型,我们获得一个空指针。>member: 访问结构体的member成员。由于空指针,这只是一个技巧,用来计算member在结构体中的偏移量。
(unsigned long)(&((type *)0)->member):- 通过
&操作符获取member在结构体中的偏移量,并将其转换为unsigned long类型。这样我们就得到了member在结构体中的字节偏移量。
- 通过
(char *)(ptr):- 将
ptr转换为char*类型,因为 C 中指针运算是按字节来计算的,char*是按字节操作指针的。
- 将
((char *)(ptr) - (unsigned long)(&((type *)0)->member)):- 这部分将
ptr(指向成员的指针)减去member的字节偏移量,得到结构体的起始地址。
- 这部分将
(type *)(...):- 最后将结果转换回
type *类型,这样我们就得到了指向整个结构体的指针。
- 最后将结果转换回
假设有如下结构体:
struct my_struct {
int a;
char b;
};如果 ptr 是指向 b 成员的指针,你可以使用宏 list_entry(ptr, my_struct, b) 来获取指向整个结构体的指针。
这个技巧在链表等数据结构中非常有用。当你只有结构体某个成员的指针(例如链表中的下一个节点的指针),但需要访问整个结构体时,使用这个宏可以通过成员的地址来反推出整个结构体的地址。
总结一下,list_entry 宏利用指针算术操作,能够通过结构体某个成员的指针来计算出整个结构体的起始地址。
版权声明:感谢您的阅读,资源整理自网络,如果您发现任何侵权行为,请联系 理科生网 管理人员,管理员将及时删除侵权内容。否则均为 理科生网 原创内容,转载时请务必以超链接(而非纯文本链接)标注来源于理科生网及本文完整链接,感谢!{alertInfo}Ahmedabad