• container_of 宏


    宏的作用

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

    如何做到

    如果要想根据结构体成员的地址求结构体的首地址,我们需要分三步:
    第一步:明确成员变量的地址;
    第二步:计算成员变量在该结构体中的偏移;
    第三步:用第一步求出的成员变量地址减去偏移值,既得出结构体的首地址

    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类型结构体的首地址
    
    不得不说,该宏运用的非常巧妙
  • 相关阅读:
    pm2部署node应用
    koa源码分析
    将vim配置成一个轻量的IDE开发工具
    私有npm下载资源
    nodejs的会话总结
    redis---安全设置
    Lua----注意事项
    Leetcode538.-Convert BST to Greater Tree-Easy
    Leetcode 230-Kth Smallest Element in a BST-Medium
    Leetcode669-Trim a Binary Search Tree-Easy
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13493631.html
Copyright © 2020-2023  润新知