【问题标题】:Receiving "double free or corruption" only when deleting first node of linked list仅在删除链表的第一个节点时收到“双重释放或损坏”
【发布时间】:2019-09-10 18:24:54
【问题描述】:

这个程序的目的是在链表的末尾添加一个可以通过ID删除的节点。

除了第一个节点之外,我可以毫无问题地删除所有节点。在删除第一个节点后尝试执行任何操作会导致意外行为,例如,如果我添加更多节点,链表将被完全清除,尝试在链表中显示数据时出现无限循环,或者出现错误“双重释放或损坏”。

删除节点

struct node* delete_node(struct node *list)

{

    struct node* p = list;
    struct node* prev, *temp;
    int id;

    printf("\nEnter ID: ");
    scanf("%d", &id);

    while(p != NULL)
    {
        if(p->id == id)
        {
            temp = p;
            p = p->next;
            prev->next = p;

            free(temp);
            printf("\nNode Deleted");
            return list;
        }
        prev = p;
        p = p->next;
    }

    printf("\nID not found");
    return list;
}

添加节点

struct node *add_node(struct node *list)

{

    struct node *p;
    int id;

    printf("\nEnter ID: ");
    scanf("%d", &id);

    for(p = list; p != NULL; p = p->next)
    {
        if(p->id == id)
        {
            printf("\nUser with this ID already exists.");
            return list;
        }
    }

    struct node *new_req;
    struct node *q = list;

    char username[UNAME_LEN], password[UNAME_LEN];

    printf("\nEnter username: ");
    read_line(username, UNAME_LEN);
    printf("\nEnter password: ");
    read_line(password, UNAME_LEN);

    new_node = malloc(sizeof(struct node));
    if(new_node == NULL)
    {
        printf("\nError allocating memory!");
        return list;
    }

    strcpy(new_node->username, username);
    strcpy(new_node->password, password);
    new_node->id = id;

    if(list == NULL)
    {
        new_node->next = NULL;
        list = new_node;
        return list;

    }


    while(q->next != NULL)
        q = q->next;

    new_node->next = q->next;
    q->next = new_node;

    return list;

}

如果我在删除第一个节点后退出程序,我会得到“双重释放或损坏”,如果我在删除第一个节点后添加一个新节点并尝试显示数据,则会导致无限循环。如果我删除第一个节点,并添加 2 个额外的节点,则链接列表将被清除,我可以退出而不会出错。

【问题讨论】:

  • 删除第一个节点后你的函数应该返回什么?
  • 抱歉回复晚了,它应该返回更新后的链表,如果它是链表中唯一的节点,它应该是 NULL,如果我理解正确的话。
  • 应该,但真的吗?
  • 在函数delete_node()中,指针prev未初始化。如果p 不为NULL 并且p->id == id,那么对prev 做的第一件事就是赋值prev->next = p。即使访问prev->next(进行分配之前的必要步骤)也会给出未定义的行为。这将解释为什么删除第一个节点会失败 - 一旦行为未定义,您的程序中的所有赌注都将失败。

标签: c linked-list


【解决方案1】:

当您删除列表中的第一个节点时,您的删除代码无法正常工作。解决它的方法可能是:

    if(p->id == id)
    {
        if(p == list)
            list = list->next;
        else
            prev->next = p->next;

        free(p);
        printf("\nNode Deleted");
        return list;
    }

并且不再需要 temp 变量。

【讨论】:

  • 抱歉回复晚了,我试过用这个还是一样的问题,我可以删除除第一个以外的所有节点
  • @IAteYourCat:你怎么称呼delete_node
  • delete_node(new_list),在我的 main 我有 struct request *new_list = NULL;
  • @IAteYourCat:应该是new_list = delete_node(new_list)
  • 这不是删除双向链表中节点的正确方法。您需要更新两个指针。
猜你喜欢
  • 2012-02-08
  • 1970-01-01
  • 2016-08-18
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多