内核中的container_of的实现

1、         功能

Container_of是从一个已知的结构体和其中一个成员及其该成员的指针,返回该结构体的首地址。字面意思:装某某成员的容器的地址。

2、        原型(在linux/kernel.h中定义)

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

ptr就是成员的指针,type是结构体类型,member是结构体成员。其中的offsetof又是一个宏定义,在linux/stddef.h中定义:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER)

offsetof(offset偏移量,意思某某成员在该结构体的偏移量)是为了求结构体中某个成员相对于结构体首地址的偏移量,但现在不知道其首地址,所以用了一个技巧,相当于把结构体移到地址0,这样取出该成员的地址就是相对于结构体首地址的偏移量。这儿有一个注意点,就是在0地址取结构体的成员的地址,这是允许的,因为我们没有取该地址里的值,而是取该地址。(事实上,此处并没有值,所以取值会出现段错误)。另外__mptr指针需转换成char*型,因为指针减去一个数相当于减去该指针类型的那么多个偏移量。

3、        代码验证如下:

#include <stdio.h>
#include <stddef.h>

struct stu{
        char name[20];
        int age;
        float score;
};

int main(void)
{
        struct stu xiaoyuan = {"xiaoyuan", 32, 56.4};

        printf("offset of age is [%d]\n", offsetof(struct stu, age));
        printf("offset of score is [%d]\n", offsetof(struct stu, score));

        printf("%d\n", (size_t)((int)&xiaoyuan.age - (int)&xiaoyuan));
        printf("%d\n", (size_t)&(((struct stu*)0)->age) );
   /* 相当于
        * printf("%d\n", (size_t)(&(((struct stu*)0)->age)- 0) );
        */

        return 0;
}


运行结果:

[root@localhost~]# ./a.out
offset of age is[20]
offset of scoreis [24]
20
20



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值