1 offset宏定义,offset是用来获取结构体成员的偏移量。
#define offsetof(type, member) (size_t)&(((type*)0)->member)
1.1((type*)0) 将内存地址0设置为type指针的起始地址。
1.2&(((type *)0)->member) 为member的地址,由于(type*)的开始地址为0,那么显然这时menber的地址也就是其偏移量。
2 container_of,container_of宏用来根据成员的地址来获取结构体的地址。
#define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );})
2.1 ptr 变量的地址
type 要获取的的结构体的名称
member ptr变量对应的名称
2.2 const typeof( ((type *)0)->member ) *__mptr = (ptr);
typeof( ((type *)0)->member ) 获取member的类型
typeof( ((type *)0)->member ) *__mptr = (ptr); 定义一个member类型的指针
2.3 (type *)( (char *)__mptr - offsetof(type,member) ),
(char *)_mptr 获取_mptr的实际地址,实际上就是ptr
offsetof(type,meber) 获取member的偏移量
(type *)( (char *)__mptr - offsetof(type,member) ) ,实际地址_mptr减去偏移量,就是type的起始地址。
3 offset和container_of测试代码
#include<stdio.h> #include<stdlib.h> #include<malloc.h> //#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) );}) typedef struct node{ int value; int key; }node_t; static void test_offset_of() { int offset_value = 0; int offset_key = 0; offset_value = offsetof(node_t,value); offset_key = offsetof(node_t,key); printf("offset_value is %d ",offset_value); printf("offset_key is %d ",offset_key); } static void test_container_of() { node_t *node1 = (node_t *)malloc(sizeof(node_t)); node_t *node2 = NULL; node_t *node3 = NULL; if(node1 == NULL) return; int *p_value = &node1->value; int *p_key = &node1->key; node2 = container_of(p_value,node_t,value); node3 = container_of(p_key,node_t,key); printf("node1 addr is %p ",node1); printf("node2 addr is %p ",node2); printf("node3 addr is %p ",node3); } int main() { test_offset_of(); test_container_of(); } ~