C - 从双向链表中删除任何节点

时间:2018-05-21 10:47:46

标签: c doubly-linked-list

尝试从双向链表中删除节点时遇到了一些麻烦。虽然我通常可以删除节点,但是当我尝试删除第一个元素时,它会崩溃我的程序并返回错误3221225477.

我用标题创建我的列表,如下所示:

typedef struct Inode2*Task;                                     
typedef struct Inode2{
        int ID;
        int Priority;
        int Status;
        char *Description;
        Person *person;
        Date   *creation;
        Date   *deadline;
        Date   *conclusion;                             
        Task next;
        Task previous;
    }Task_node2;    

Task TaskCreate()                                                                                                           {
    Task aux=(Task)malloc(sizeof(Task));
    aux->next=NULL;
    aux->previous=NULL;
    return aux;
}

据我所知,这是创建一个带有标题的列表,我可以进一步操作它。

我有一个函数在这个List的尾部插入一个节点。这似乎完美无缺。

每当我在第一个元素上使用此删除功能时,它就会崩溃:

int TaskRemove(Task h,int IDREMOVE)                                                                                         {
    int val;
    for(;h;h=h->next)
    {
        if (h->ID==IDREMOVE)
        {
            h->previous->next = h->next;
            val++;
            if (h->previous->previous==NULL)
            {
                h->previous->next = h->next;
            }
        }
    }
    if (val==0)
    {
        printf("\n\tNo node with such ID\n");
        sleep(1);
    }
    return val;
}

这适用于除最后一个元素之外的所有元素。发生了什么?提前谢谢。

2 个答案:

答案 0 :(得分:1)

问题是您的代码访问一个两个远的节点而不检查相应的一个离开节点是否存在。删除列表中的最后一个节点会给您带来类似的问题。

您需要NULL - 在向其应用->运算符之前检查每个指针。具体而言,检查h->previous->previous == NULL的代码需要首先确保h->previous不是NULL。您需要在执行两次检查或分配的所有位置添加NULL检查第一个指针。

注意:您的代码还有其他问题,例如,malloc(sizeof(Task))会产生大小不正确的内存。混淆的根本情况是Task是指针类型,但它没有星号使用。如果可能,您应该直接使用Inode2*或将Inode2重命名为Task以提高可读性,从而避免出现这种情况。

答案 1 :(得分:0)

代码的第一个问题是如何为节点分配内存。

Task aux=(Task)malloc(sizeof(Task));

此行分配sizeof(Task)个字节的内存。 Task是指针,而不是实际节点。根据编译器的不同,它很可能会为指针分配足够的空间。您应该使用以下内容为Inode2分配空间:

Task aux=(Task)malloc(sizeof(struct Inode2));

第二个问题是:

h->previous->next = h->next;
val++;
if (h->previous->previous==NULL)
{
    h->previous->next = h->next;
}

对于第一个元素,h->previous应为NULL,因此当您尝试访问h->previous->next时,程序正在尝试访问NULL指针,这会导致崩溃。在尝试进一步访问之前,您必须先检查h->previous是否为NULL

注意:

  • 如评论中所述,请执行 NOT typedef指针。
  • 你说它在第一个元素上崩溃,然后表示它适用于除 last 之外的所有元素。我假设前者。