首页 > 代码库 > list链表之:从链表删除一个节点list_del

list链表之:从链表删除一个节点list_del

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


list链表之:从链表删除一个节点list_del