【问题标题】:C - Deleting any node from a doubly linked listC - 从双向链表中删除任何节点
【发布时间】:2018-05-21 10:47:45
【问题描述】:

我在尝试从双向链表中删除节点时遇到了一些麻烦。虽然我通常可以删除节点,但当我尝试删除第一个元素时,它会使我的程序崩溃并返回错误 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;
}

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

我有一个函数可以在这个列表的尾部插入一个节点。这似乎工作得很好。

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

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;
}

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

【问题讨论】:

  • OT:typedef struct Inode2*Task; 哦,不要键入定义指针。尤其是像Task 这样的陌生名字。您的代码对其他人和 - 可能 - 对您自己来说都是不可读的
  • 您的第一个错误(由于指针的类型 def)在这里:Task aux=(Task)malloc(sizeof(Task));。应该(至少)Task aux=malloc(sizeof(struct Inode2));,但更好的是:Task_node2* aux=malloc(sizeof *aux);

标签: c doubly-linked-list


【解决方案1】:

问题是您的代码访问了一个双向节点,而没有检查相应的单向节点是否存在。删除列表中的最后一个节点会给您带来类似的问题。

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

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

【讨论】:

    【解决方案2】:

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

    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 指针。
    • 您说它在 first 元素上崩溃,然后说它在除 last 之外的所有元素上都有效。我假设是前者。

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 1970-01-01
      • 2016-10-09
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多