宏的作用

该宏的作用就是根据结构体中一个成员变量的地址求结构体首地址

如何做到

如果要想根据结构体成员的地址求结构体的首地址,我们需要分三步:

第一步:明确成员变量的地址;

第二步:计算成员变量在该结构体中的偏移;

第三步:用第一步求出的成员变量地址减去偏移值,既得出结构体的首地址

container_of宏如何做的

首先我们先看下该宏的原型:

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

根据上面我们列出的三步,我们分开来看:

第一步:明确成员变量地址

const typeof( ((type *)0)->member ) *__mptr = (ptr);
此处将成员变量地址ptr,赋值给临时变量__mptr
typeof是标准C库中的函数,函数返回参数的数据类型,此处即返回成员变量member的类型,并根据member的类型定义临时指针变量__mptr

第二步:计算成员变量在结构体中的偏移

offsetof(type,member)
offsetof为标准C库中的函数,函数作用就是求出member成员在结构体中的偏移。 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
这个宏的运行机理如下:
一共4步
1. ( (TYPE *)0 ) 将零转型为TYPE类型指针;
2. ((TYPE *)0)->MEMBER 访问结构中的数据成员;
3. &( ( (TYPE *)0 )->MEMBER )取出数据成员的地址;
4.(size_t)(&(((TYPE*)0)->MEMBER))结果转换类型。巧妙之处在于将0转换成(TYPE*),结构以内存空间首地址0作为起始地址,则成员地址自然为偏移地址;

第三步:结构体成员变量地址减去成员变量的偏移

(type *)( (char *)__mptr - offsetof(type,member) );
取成员变量的地址__mptr减去该成员变量在结构体中的偏移,即可得到type类型结构体的首地址
不得不说,该宏运用的非常巧妙

container_of 宏的更多相关文章

  1. linux中offsetof与container_of宏定义

    linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER)    ((size_t) &((TYPE *)0)->M ...

  2. (转)offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  3. container_of宏定义分析---linux内核

    问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...

  4. container_of宏剖析

    container_of宏剖析//该宏位于include/linux/kernel.h 1.定义格式 /** * container_of - cast a member of a structure ...

  5. 内核中container_of宏的详细分析【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...

  6. offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  7. container_of宏

    title: container_of宏 date: 2019/7/24 15:49:26 toc: true --- container_of宏 解析 在linux链表结构中有这样一个宏,通过成员变 ...

  8. offsetof与container_of宏分析

    offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...

  9. typeof, offsetof, container_of宏

    container_of宏实现如下: #define container_of(ptr, type, member) ({ \ )->member ) *__mptr = (ptr); \ (t ...

  10. offsetof宏与container_of宏

    offsetof宏与container_of宏1.由结构体指针进而访问各元素的原理(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个时候其实是 ...

随机推荐

  1. 第二十二章、 Model/View便利类树型部件QTreeWidget

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...

  2. PyQt(Python+Qt)学习随笔:QTreeView树形视图的headerHiden属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTreeView树形视图的headerHiden属性用于控制视图中是否隐藏标题,为True隐藏,否 ...

  3. 混合云存储打开的正确姿势——腾讯云存储网关 CSG

    近年来,随着云计算的发展,越来越多的企业选择将IT系统基础设施转移到云上,上云有助于推动企业加快信息化.数字化.智能化的转型,但是很多企业对传统的业务系统依赖程度较高,短时间内将业务迁移上云将会面临很 ...

  4. 深入分析 Java 乐观锁

    前言 激烈的锁竞争,会造成线程阻塞挂起,导致系统的上下文切换,增加系统的性能开销.那有没有不阻塞线程,且保证线程安全的机制呢?--乐观锁. 乐观锁是什么? 操作共享资源时,总是很乐观,认为自己可以成功 ...

  5. luogu P6835 概率DP 期望

    luogu P6835 概率DP 期望 洛谷 P6835 原题链接 题意 n + 1个节点,第i个节点都有指向i + 1的一条单向路,现在给他们添加m条边,每条边都从一个节点指向小于等于自己的一个节点 ...

  6. TMOOC 1969 开锁

    update on 2020.2.28 时隔近日重新想这道题,其实复杂度正确的解法是 可持久化 01 Trie. 考虑对于每一个 \(a[i]\),考虑能将它作为最大值的最大包容区间 \([l, r] ...

  7. geoserver的demo使用过程

    先贴一个效果图,使用的geoserver版本2.18.0,需要对应版本插件netcdf插件[Extensions>Coverage Formats>NetCDF],使用tomcat8进行发 ...

  8. 【Django Python版本对应】

    使用Python36 时应该使用Django版本1.11.4 pip install django==1.11.4 版本对应表: Django version Python versions 1.8 ...

  9. 没有部署ingress pod的woker节点telnet slb的80 443端口不通

    一,问题描述 没有部署ingress pod的woker节点telnet slb的80 443端口不通 二,解决办法 方法一:改用svc地址调用 方法二:让每台woker节点都部署ingress po ...

  10. 面试 11-01.ES6:模块化的使用和编译环境

    11-01.ES6:模块化的使用和编译环境 #前言 #ES6的主要内容 模块化的使用和编译环境 Class与JS构造函数的区别 Promise的用法 ES6其他常用功能 本文来讲"模块化的使 ...