C 指针操作分析

本文详细分析了Linux内核代码中关于删除路由链表节点的实现。通过示例代码,解释了指针操作`rp=&r->rt_next`和`*rp=r->rt_next`的功能,指出它们如何更新链表结构,从而实现删除不匹配条件的节点。文章适合有一定C语言和Linux内核基础的读者深入理解指针和链表操作。

        最近学习Linux内核代码,两句指针代码顿时让我感觉自己的指针功底还是欠缺。在此对代码重新做了梳理、分析及记录。

        源代码结构也挺简单。如下:

static struct rtable *rt_base = NULL;

static void rt_del(unsigned long dst, char *devname)
{
	struct rtable *r, **rp;
	rp = &rt_base;
	
	// …………  省略部分代码
	while((r = *rp) != NULL) 
	{
		/* Make sure both the destination and the device match */
		if ( r->rt_dst != dst ||
		(devname != NULL && strcmp((r->rt_dev)->name,devname) != 0) )
		{
			rp = &r->rt_next;
			continue;
		}

		*rp = r->rt_next;
		
		// …………  省略部分代码
		kfree_s(r, sizeof(struct rtable));
	} 
}

        在程序初始化时 rt_base 是一个指向路由链表头的指针;上述代码中有两行相似且不容易理解的代码:1、rp = &r->rt_next;  2、*rp = r->rt_next; 以下做以分析。

        首先将上述指针的结构及指向如下图:

      上图画出了代码中涉及三个变量:struct rtable  *rt_base;struct rtable *r, **rp 的结构在起初第一次刚进while循环时的指针所指位置(图中所有的地址都是自己假设的;假设链表节点内容长度为0x10,可以算出第一个节点的next指针的地址为:0x1011)。

        假设第一次进入while循环且if条件成立,此时 r = *rp 执行后:此时 r (值为:0x1001)指向 rt_base 链表的表头 ,&r->rt_next 为 0x1011; 此时函数会执行 rp = &r->rt_next此时 rp 存储中的值由0x2020(rt_base 指针的地址)变为 0x1011(链表第一个节点的next指针的地址)。此时的 *rp (值为:0x1041)指向链表的第二个节点,continue 继续跳回while执行。

        假设第二次进入while循环且if条件不成立,此时 r = *rp 执行后:r (值为:0x1041)指向链表的第二个节点;r->rt_next 为链表的第三个节点;rp(值为:0x1011)存放的是第一个节点的next指针的地址;此时执行 *rp = r->rt_next;即为:将第一个节点的next指针指向第三个节点。

        所以总结为:该函数是删除不满足 if 条件的节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值