list_head双向链表的删除问题
来源:互联网 发布:linux ftp 端口设置 编辑:程序博客网 时间:2024/06/05 14:38
下面的程序,目的是遍历一条链表,逐条的删除没一个节点。
[code]
struct list_head *listp;
struct arethe* arethep;
list_for_each(listp, arethe_list)
{
arethep = list_entry(listp, struct arethe, list_entry);
list_del(listp);
kfree(arethep);
}
[/code]
但是,在执行时,会出现内存引用出错的问题. 在分析list_del与list_for_each后,发现在list_del之后,list_for_each以无法再遍历剩下的链表。因为listp->next与listp->prev与链表都以没有关联。此时,采用list_for_each_safe(pos,n,head)宏可解决问题。该宏与前者的区别主要是采用了另外一个指针n来存储pos的下一个节点的位置,因此在删除某个节点以后,保存了剩下的节点的信息。相应代码应修改为如下:
[code]
struct list_head *listp;
struct list_head *listn;
struct arethe* arethep;
list_for_each_safe(listp, listn, arethe_list)
{
arethep = list_entry(listp, struct arethe, list_entry);
list_del(listp);
kfree(arethep);
}
arethep = list_entry(listp, struct arethe, list_entry);
printk("arethe_list->arethe_ip: %d/n", arethep->arethe_ip);
[/code]
有一点需要注意的是,无论是list_for_each还是list_for_each_safe,都遍历不到头结点.
另附上一段list_head的操作范例:
[code]
#include <linux/module.h>
#include <linux/kernel.h>
#include <arethe_dbg.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arethe");
struct arethe{
struct list_head list_entry;
int arethe_ip;
};
int arethe_ip = 0;
struct list_head *arethe_list;
int list_head_init(void)
{
struct list_head *listp;
struct arethe *arethep;
int arethe_num = 10;
int i = 0;
for(i=0; i < arethe_num; i++)
{
arethep = kzalloc(sizeof(*arethep), GFP_KERNEL);
arethe_ip++;
arethep->arethe_ip = arethe_ip;
printk(KERN_ALERT"arethe_ip: %d/n", arethe_ip);
INIT_LIST_HEAD(&arethep->list_entry);
if(!arethe_list)
arethe_list = &arethep->list_entry;
else
list_add(arethep, arethe_list);
}
list_for_each(listp, arethe_list)
{
arethep = list_entry(listp, struct arethe, list_entry);
printk(KERN_ALERT"arethe->arethe_ip: %d/n", arethep->arethe_ip);
}
arethep = list_entry(listp, struct arethe, list_entry);
printk(KERN_ALERT"arethe->arethe_ip: %d/n", arethep->arethe_ip);
return 0;
}
void list_head_exit(void)
{
struct list_head *listp;
struct list_head *listn;
struct arethe* arethep;
list_for_each_safe(listp, listn, arethe_list)
{
arethep = list_entry(listp, struct arethe, list_entry);
printk(KERN_ALERT"Del: arethep->ip: %d/n", arethep->arethe_ip);
//if(listp->next != listp && listp->prev != listp)
list_del(listp);
kfree(arethep);
}
arethep = list_entry(listp, struct arethe, list_entry);
printk("arethe_list->arethe_ip: %d/n", arethep->arethe_ip);
}
module_init(list_head_init);
module_exit(list_head_exit);
[/code]
运行结果为:
[code]
arethe_ip: 1
arethe_ip: 2
arethe_ip: 3
arethe_ip: 4
arethe_ip: 5
arethe_ip: 6
arethe_ip: 7
arethe_ip: 8
arethe_ip: 9
arethe_ip: 10
arethe->arethe_ip: 10
arethe->arethe_ip: 9
arethe->arethe_ip: 8
arethe->arethe_ip: 7
arethe->arethe_ip: 6
arethe->arethe_ip: 5
arethe->arethe_ip: 4
arethe->arethe_ip: 3
arethe->arethe_ip: 2
arethe->arethe_ip: 1
Del: arethep->ip: 10
Del: arethep->ip: 9
Del: arethep->ip: 8
Del: arethep->ip: 7
Del: arethep->ip: 6
Del: arethep->ip: 5
Del: arethep->ip: 4
Del: arethep->ip: 3
Del: arethep->ip: 2
arethe_list->arethe_ip: 1
[/code]
- list_head双向链表的删除问题
- list_head 双向循环链表的结构
- 双向循环链表list_head
- 双向链表 struct list_head 个人认识
- linux内核源码“双向链表list_head”
- C语言之list_head双向链表
- 双向链表删除问题
- 内核中常用的双向链表数据结构(list_head)详解
- 通用链表(内核双向循环链表list_head)
- 深入浅出linux内核源代码之双向链表list_head(上)
- 深入浅出linux内核源代码之双向链表list_head(下)
- linux 内核分析之list_head 双向链表结构
- 深入浅出linux内核源代码之双向链表list_head(上)
- 深入浅出linux内核源代码之双向链表list_head(下)
- 深入浅出linux内核源代码之双向链表list_head(上)
- 深入浅出linux内核源代码之双向链表list_head(上)
- 深入浅出linux内核源代码之双向链表list_head(下)
- 深入浅出linux内核源代码之双向链表list_head(上)
- Spring的DataAccessException
- gedit打开文件提示错误
- JAVA连接数据库大全
- UT-S3C6410开发板 7寸液晶屏/2D/3D硬件图形加速/SD卡+USB2.0升级系统/QQ
- zz互联网企业衰亡史
- list_head双向链表的删除问题
- 反射相关
- 为GridView“删除”列添加确认对话框
- 数据库中User和Schema的关系
- 开发板UT-S3C6410 telnet Linux主机的详细设置(三)【友坚恒天科技】
- ELF文件结构
- 知道 BAPI 函数,如何查找其对应的业务对象?【转载】
- 修改表和存储过程的所有者
- 利用自定义HEADER屏蔽搜索引擎