从链表删除一个节点使用接口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