- 宏 offsetof
//./include/linux/stddef.h
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
众所周知,对内存地址为 0 进行解引用肯定有问题。但是这里的 0 并不是用来解引用的,而是用来简化计算的。C 对于内存的处理很随意,本宏中将地址 0 作为 TYPE 类型去使用,但是全程没有进行解引用,&((TYPE*)0)->MEMBER 的含义是将 地址0 作为 TYPE 去使用的前提下,返回成员字段 MEMBER的地址。因为这里假定 0作为 TYPE 的地址,因此得到的值便可以认为是 MEMBER 在内存中在TYPE 中的偏移了。
-
利用这个方法,可以根据一个成员变量的地址,反推出其宿主的地址。Linux 内核中的双向链表 list_head 本身不存储数据,而是作为数据的成员变量进行侵入式。也是利用这个原理。
网友评论