container_of宏是用在已知一个struct中的元素地址,计算出此元素所在结构体的首地址。
一、定义
1 |
|
其中 ptr 指的是元素的指针,type是结构体的类型,member是元素类型。
举个例子:
1 |
|
运行结果:
1 | container_of_addr = 1429a730 |
从这里可以看出,通过一个struct的成员的地址 ptr ,结构体的类型 struct Test,成员名 m_b。就可以得到ptr所对应的结构体变量的首地址。
二、原理
原理其实很简单,一句话就可以概括,就是通过元素的地址减去结构体成员在结构体中的地址偏移。如下图:
其中:offsetof(type, member)函数就是用来求offset(结构体成员在结构体中的地址偏移)。来看一看offsetof的定义:
1 |
这里的 (type *)0 表示,骗编译器我有一个起始地址为0的类型为type的变量,&((TYPE *)0)->MEMBER 所以member的地址就是member在struct中的地址偏移。
通过 head = ptr - offset 就可以得到struct的首地址,再将head强制转换为相应的struct类型的指针即可。