ZoyaPatel

C 语言低层技巧中的王者级工具:container_of 技巧

SohaniSharma
## “container_of 技术” 是 C 语言低层技巧中的王者级工具,它的精髓在于:“从结构体中的成员指针,反推整个结构体的地址。”理科生网链接地址:https://www.lksr.net/2025/11/c-containerof.html{alertInfo}

由人工编写审核,非AI生成内容,请放心观看!

{getToc} $title={文章目录}

container_of 技术” 是 C 语言低层技巧中的王者级工具,它的精髓在于:“从结构体中的成员指针,反推整个结构体的地址。”

C 语言低层技巧中的王者级工具:container_of 技巧
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)))

1. 参数解析:

  • ptr: 结构体成员的指针。
  • type: 结构体的类型(即 member 所属的结构体类型)。
  • member: 结构体中的某个成员的名称。

2. 宏的分解:

让我们逐步分析宏中的每个部分:

  • &((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 * 类型,这样我们就得到了指向整个结构体的指针。

3. 举例:

假设有如下结构体:

struct my_struct {
    int a;
    char b;
};

如果 ptr 是指向 b 成员的指针,你可以使用宏 list_entry(ptr, my_struct, b) 来获取指向整个结构体的指针。

4. 为什么要这样做?

这个技巧在链表等数据结构中非常有用。当你只有结构体某个成员的指针(例如链表中的下一个节点的指针),但需要访问整个结构体时,使用这个宏可以通过成员的地址来反推出整个结构体的地址。

总结一下,list_entry 宏利用指针算术操作,能够通过结构体某个成员的指针来计算出整个结构体的起始地址。

版权声明:感谢您的阅读,资源整理自网络,如果您发现任何侵权行为,请联系 理科生网 管理人员,管理员将及时删除侵权内容。否则均为 理科生网 原创内容,转载时请务必以超链接(而非纯文本链接)标注来源于理科生网及本文完整链接,感谢!{alertInfo}

Ahmedabad
Kolkata
Hyderabad
后一页 Bangalore 前一页

Random Manga

Ads

نموذج الاتصال