883@ container of() 函数解析

本文详细介绍了Linux内核编程中常用的container_of和offsetof宏的用法和原理。container_of宏通过成员地址计算结构体起始地址,offsetof宏则用于获取成员在结构体内的偏移量。文章强调了0指针在内核编程中的特殊意义,并解释了内核代码的严谨性,如通过类型检查避免潜在错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

container of() 


在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member)

已知 结构体 type 的成员 member 的地址 ptr,求解结构体type的起始地址。

type的起始地址 = ptr - size      (这里需要都转换为char *,因为它为单位字节)。

container of函数原型:

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

其次为 offserof 函数原型:

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

(一)0 指针的使用 :

#include<stdio.h>
 
struct test
{
    char i ;
    int j;
    char k;
};
 
int main()
{
    struct test temp;
    printf("&temp = %p\n",  &temp);   
    printf("&temp.k = %p\n",  &temp.k);
    printf("&  ((struct test *)0)->k = %d\n",  (  (int)&  ((struct test *)0)->k )  );
 
}
 编译运行,可以得到如下结果:

&temp = 0xbf9815b4
&temp.k = 0xbf9815bc
&((struct test *)0)->k = 8


 什么意思看到了吧,自定义的结构体有三个变量:i,j,k。

因为有字节对齐要求,所以该结构体大小为4bytes * 3 =12 bytes.  

而&((struct test *)0)->k 的作用就是求 k到结构体temp起始地址的字节数大小(就是我们的size)。

在这里0被强制转化为struct test *型, 它的作用就是作为指向该结构体起始地址的指针,就是作为指向该结构体起始地址的指针,就是作为指向该结构体起始地址的指针, 而&((struct test *)0)->k  的作用便是求k到该起始指针的字节数。。。

其实是求相对地址,起始地址为0,则&k的值便是size大小(注:打印时因为需要整型,所以有个int强转)所以我们便可以求我们需要的 size 了  。

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
所以offsetof()的作用就是求我们梦寐以求的size, 并以size_t形式返回(size_t: 无符号整型)。

(二) 内核编程的严谨性   

#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);  


它的作用是什么呢? 其实没什么作用,但就形式而言 _mptr = ptr,  那为什么要要定义一个一样的变量呢???

如果开发者使用时输入的参数有问题:ptr与member类型不匹配,编译时便会有warnning, 但是如果去掉改行,那个就没有了,而这个警告恰恰是必须的(防止出错有不知道错误在哪里)。。。这严谨性可以吧

typeof( ((type *)0)->member )
   它的作用是获取member的类型仅此而已。至此基本结束

(三) 总结

container_of(ptr, type,member)函数的实现包括两部分:

1.  判断ptr 与 member 是否为同意类型

2.  计算size大小,结构体的起始地址 = (type *)((char *)ptr - size)   (注:强转为该结构体指针)

现在我们知道container_of()的作用就是通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。

container_of(ptr,type,member),   这里面有  ptr,type,member  分别代表指针、类型、成员。



原文链接:https://blog.youkuaiyun.com/s2603898260/article/details/79371024

内容概要:本文档详细介绍了基于MATLAB实现的无人机三维路径规划项目,核心算法采用蒙特卡罗树搜索(MCTS)。项目旨在解决无人机在复杂三维环境中自主路径规划的问题,通过MCTS的随机模拟与渐进式搜索机制,实现高效、智能化的路径规划。项目不仅考虑静态环境建模,还集成了障碍物检测与避障机制,确保无人机飞行的安全性和效率。文档涵盖了从环境准备、数据处理、算法设计与实现、模型训练与预测、性能评估到GUI界面设计的完整流程,并提供了详细的代码示例。此外,项目采用模块化设计,支持多无人机协同路径规划、动态环境实时路径重规划等未来改进方向。 适合人群:具备一定编程基础,特别是熟悉MATLAB和无人机技术的研发人员;从事无人机路径规划、智能导航系统开发的工程师;对MCTS算法感兴趣的算法研究人员。 使用场景及目标:①理解MCTS算法在三维路径规划中的应用;②掌握基于MATLAB的无人机路径规划项目开发全流程;③学习如何通过MCTS算法优化无人机在复杂环境中的飞行路径,提高飞行安全性和效率;④为后续多无人机协同规划、动态环境实时调整等高级应用打下基础。 其他说明:项目不仅提供了详细的理论解释和技术实现,还特别关注了实际应用中的挑战和解决方案。例如,通过多阶段优化与迭代增强机制提升路径质量,结合环境建模与障碍物感知保障路径安全,利用GPU加速推理提升计算效率等。此外,项目还强调了代码模块化与调试便利性,便于后续功能扩展和性能优化。项目未来改进方向包括引入深度强化学习辅助路径规划、扩展至多无人机协同路径规划、增强动态环境实时路径重规划能力等,展示了广阔的应用前景和发展潜力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值