个人对container_of宏的理解

container_of宏的作用太神奇了,本人想去了解它具体是怎样实现的,查阅了很多资料发现讲解的不是通俗易懂,当然一些讲的大体上还是能够理解,下面我将我查阅到的资料重新整理,希望给大家更好的理解container_of宏.

内核中container_of宏的定义:

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


((type *)0)->member 我根据我个人的理解解释一下,如果不对的话,请指正:通过以0地址做中转来间接获取该结构体中的成员变量(当然也可以用其他地址),比如如下,我通过编程来打印出来

struct mytest
{
        int i;
        int j;
        float k;
        char n;
        double m
};
        //printf("((struct mytest *)0)->j:%d\n",((struct mytest *)0)->j);//这句话会导致段错误,个人猜测可能是对0地址有写入了,导致的错误?希望有人来帮我解惑.
        printf("&((struct mytest *)0)->j :0x%x\n",&((struct mytest *)0)->j); // 打印输出0x4  如果以0地址来存放struct mytest 的话,j的值放在4地址处
        printf("&((struct mytest *)1)->j :0x%x\n",&((struct mytest *)1)->j); //0x5   
        printf("&((struct mytest *)2)->j :0x%x\n",&((struct mytest *)2)->j);//0x6    

通过上面打印地址信息可以知道:&((type *)0)->member(即offsetof 宏的展开)是menber以哪个地址为基准来偏移的,

typeof( ((type *)0)->member )网上都说是获取member变量的类型,本人深究不了只好记得它是获取类型就行.

假设type是struct mytest ,member 是 j.那member的类型就是int类型,所以const typeof( ((type *)0)->member ) *__mptr  转换为:const int * __mptr .

const typeof( ((type *)0)->member ) *__mptr = (ptr);就是将__mptr指向ptr的地址.我这里打印出来的地址值:0x804a024

offsetof(type,member)展开就是上面&((struct mytest *)0)->j 打印的值.

(type *)( (char *)__mptr - offsetof(type,member) ); __mptr的地址值 - member以0地址为基准(这里(type *)0,所以以0为基准)的偏移值:即0x804a024 - 0x4 = 0x804a020

我打印struct mytest结构体的首地址出来的值:0x804a020,和container_of打印出来的值是一样的,

以上是个人对container_of宏的理解,如果有错误之处恳请指正.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值