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 {}{}比较
86 0
|
4月前
|
编译器 C++
offsetof宏的使用、模拟实现及 (size_t)&(((struct_type*)0)->mem_name)的解释
offsetof宏的使用、模拟实现及 (size_t)&(((struct_type*)0)->mem_name)的解释
|
JSON Go 数据格式
Go struct tag能否设置默认值?
Go struct tag能否设置默认值?
在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
|
编译器 C++
尽量以const、enum、inline替换#define
尽量以const、enum、inline替换#define
178 0
尽量以const、enum、inline替换#define
|
编译器 C++
Effective C++条款 02:尽量以 const, enum, inline 替换 #define
Effective C++条款 02:尽量以 const, enum, inline 替换 #define
129 0
|
编译器 Linux C语言
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction
694 0
报错storage size of ‘sa’ isn’t known,当使用std=c99编译struct sigaction
|
程序员 编译器 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
864 0
|
NoSQL
gdb打印结构体member offset
linux的crash有个好处就是可以方便打印结构体成员变量的offset, 有时候对汇编的时候, 需要偏移, 可惜crash需要一个活体才行, 不能单纯的vmlinux, 因为它就是这么设计的 gdb天生没有这个功能, 不过python可以实现 cat offset.py import gdb class Offsets(gdb.Command): def __in
2891 0
|
C++
C++:为什么unique_ptr的Deleter是模板类型参数,而shared_ptr的Deleter不是?
为什么unique_ptr的Deleter是模板类型参数,而shared_ptr的Deleter不是? template <class T, class D = default_delete<T>> class unique_ptr { public: .
1426 0