从链表删除一个节点使用接口list_del,使用list_del时要非常注意。
list_del的实现如下:
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
其实就是将该节点的prev指向next,next指向prev,将本节点跨过去
然后将本节点的next和prev都赋值为一个无意义的值。
所以这里如果想让循环继续下去的话,需要先将本节点的prev节点暂存起来,
然后执行list_del,然后再将prev节点恢复成当前节点,也就是在循环中要这么处理:
/* del a node from list */
list_for_each(tmp, &list_use_head)
{
struct list_head *tmp1;
pstListTmp = list_entry(tmp, struct stListUse, list);
printf("index:%d, name:%s, pointer:%s\n", pstListTmp->index, pstListTmp->name, pstListTmp->pointer);
if(5 == pstListTmp->index)
{
printf("del node 5 from list!\n");
tmp1=tmp->prev;
list_del(tmp);
tmp=tmp1;
}
}root@ubuntu:/mnt/shared/kernelbox/list# cat listuse.c
#include "list.h"
struct stListUse
{
char name[32];
char *pointer;
int index;
struct list_head list;
};
#define STR_LEN_IN_NODE 32
LIST_HEAD(list_use_head);
struct stListUse *pstListNode;
int main(int argc, char *argv[])
{
int i;
char nametmp[STR_LEN_IN_NODE];
struct stListUse *pstListTmp;
struct list_head *tmp;
printf("enter listuse.c/main()\n");
for(i=0; i<10; i++)
{
pstListNode = (struct stListUse *)malloc(sizeof(struct stListUse));
memset(pstListNode, 0, sizeof(struct stListUse));
/* init node's member: index */
pstListNode->index = i;
/* init node's member: name */
memset(nametmp, 0, STR_LEN_IN_NODE);
sprintf(nametmp, "name%d", i);
strcpy(pstListNode->name, nametmp);
/* init node's member: pointer */
pstListNode->pointer =(char *)malloc(STR_LEN_IN_NODE * sizeof(char));
memset(pstListNode->pointer, 0, sizeof(STR_LEN_IN_NODE * sizeof(char)));
memset(nametmp, 0, STR_LEN_IN_NODE);
sprintf(nametmp, "pointer%d", i);
strcpy(pstListNode->pointer, nametmp);
/* add node i to list list_use_head */
#if 0
list_add(&pstListNode->list, &list_use_head);
#endif
list_add_tail(&pstListNode->list, &list_use_head);
}
/* print list */
pstListTmp =(struct stListUse *)malloc(sizeof(struct stListUse));
printf("*********************************************\n");
list_for_each(tmp, &list_use_head)
{
pstListTmp = list_entry(tmp, struct stListUse, list);
printf("index:%d, name:%s, pointer:%s\n", pstListTmp->index, pstListTmp->name, pstListTmp->pointer);
}
printf("list_usr_head:%p\n", list_use_head);
printf("tmp:%p\n", tmp);
printf("*********************************************\n");
/* del a node from list */
list_for_each(tmp, &list_use_head)
{
struct list_head *tmp1;
pstListTmp = list_entry(tmp, struct stListUse, list);
printf("index:%d, name:%s, pointer:%s\n", pstListTmp->index, pstListTmp->name, pstListTmp->pointer);
if(5 == pstListTmp->index)
{
printf("del node 5 from list!\n");
tmp1=tmp->prev;
list_del(tmp);
tmp=tmp1;
}
}
printf("list_usr_head:%p\n", list_use_head);
printf("tmp:%p\n", tmp);
/* print list */
printf("*********************************************\n");
list_for_each(tmp, &list_use_head)
{
pstListTmp = list_entry(tmp, struct stListUse, list);
printf("index:%d, name:%s, pointer:%s\n", pstListTmp->index, pstListTmp->name, pstListTmp->pointer);
}
printf("list_usr_head:%p\n", list_use_head);
printf("tmp:%p\n", tmp);
printf("*********************************************\n");
return 0;
}
原文地址:http://blog.csdn.net/xiangpingli/article/details/40900907