container_of(ptr,type,member)宏

简介: 详细解释了container_of(ptr,type,member)宏的用途

1、作用
已知结构体type的成员member的地址ptr,计算出type结构体的首地址。

2、原型

define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

define container_of(ptr, type, member) ({ \

    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})

3、typeof关键字
  typeof的作用就是获取对象的数据类型。typeof没有被定义在C标准库中,而是GNU C的拓展。用法如下:
int a = 0;

typeof(a) b = 1; //b的数据类型是int

4、零值指针
零值指针顾名思义就是值为0的指针,即地址为0,同时其可以是任何类型的指针,可以是void,char,int*等等。

5、offset()宏获取偏移地址
  offset()获取偏移地址就是巧妙地应用了0地址指针,将0指针强制转化为所指定的type类型,再通过其访问结构体内成员,并通过&获取成员的地址。由于该强制转化而来的结构体位于0地址,所以获取的成员的地址即是该成员与结构体起始地址的偏移地址。

6、container_of()宏解析
const typeof( ((type )0)->member ) mptr = (ptr); //定义一个临时指针变量mptr,类型是结构体成员member的数据类型

(type )( (char )__mptr - offsetof(type,member) ) //结构体成员地址减去偏移量就是结构体的首地址

相关文章
|
存储 Go
Go空结构体struct {}
struct {}介绍、使用场景、和struct {}{}比较
105 0
|
6月前
|
编译器 C++
offsetof宏的使用、模拟实现及 (size_t)&(((struct_type*)0)->mem_name)的解释
offsetof宏的使用、模拟实现及 (size_t)&(((struct_type*)0)->mem_name)的解释
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
161 0
error:‘struct vm_fault‘ has no member named ‘virtual_address‘
|
编译器 C++
尽量以const、enum、inline替换#define
尽量以const、enum、inline替换#define
186 0
尽量以const、enum、inline替换#define
|
编译器 C++
Effective C++条款 02:尽量以 const, enum, inline 替换 #define
Effective C++条款 02:尽量以 const, enum, inline 替换 #define
135 0
|
程序员 编译器 C语言
解决办法:undefined reference to symbol '_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
解决办法:undefined reference to symbol '_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
921 0
|
NoSQL
gdb打印结构体member offset
linux的crash有个好处就是可以方便打印结构体成员变量的offset, 有时候对汇编的时候, 需要偏移, 可惜crash需要一个活体才行, 不能单纯的vmlinux, 因为它就是这么设计的 gdb天生没有这个功能, 不过python可以实现 cat offset.py import gdb class Offsets(gdb.Command): def __in
2918 0
|
Linux C语言
利用__attribute__((section()))构建初始化函数表【转】
转自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=779762953029c0e0946c22ef2bb0b754&chksm=810f28a1b678a1b747520ba3ee47c9e...
1761 0