C “接收”;“双重自由或腐败”;仅当删除链表的第一个节点时

C “接收”;“双重自由或腐败”;仅当删除链表的第一个节点时,c,linked-list,C,Linked List,该程序的目的是在链表的末尾添加一个节点,该节点可以通过ID删除 除第一个节点外,我可以删除每个节点而不出现问题。删除第一个节点后尝试执行任何操作都会导致意外行为,例如,如果添加更多节点,链表将被完全清除,尝试在链表中显示数据时出现无限循环,或者出现错误“双重释放或损坏” 删除节点 struct node* delete_node(struct node *list) { struct node* p = list; struct node* prev, *temp;

该程序的目的是在链表的末尾添加一个节点,该节点可以通过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;

}

如果我在删除第一个节点后退出程序,我将获得“双重自由或损坏”,如果我在删除第一个节点后添加一个新节点并尝试显示数据,它将导致无限循环。如果我删除了第一个节点,并添加了两个额外的节点,则链接列表将被清除,并且我可以毫无错误地退出。

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

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

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

而且不再需要
temp
变量。

删除第一个节点后,您的函数应该返回什么?很抱歉,响应太晚,它应该返回更新的链接列表,如果它是链接列表中唯一的节点,如果我理解正确,它应该为NULL。它应该,但确实如此?在函数
delete_node()
中,指针
prev
未初始化。如果
p
不为空且
p->id==id
则对
prev
所做的第一件事是赋值
prev->next=p
。甚至访问
prev->next
(执行分配之前的必要步骤)也会产生未定义的行为。这将解释为什么删除第一个节点失败-一旦行为未定义,您的程序中的所有赌注都将被取消。很抱歉,响应太晚,我尝试使用此选项,但仍然存在相同的问题,我可以删除除第一个节点外的所有节点one@IAteYourCat:如何调用
删除节点
?删除节点(新列表),在我的main中,我有struct request*new_list=NULL@IAteYourCat:它应该是
new\u list=delete\u node(new\u list)
。这不是删除双链接列表中节点的正确方法。您需要更新两个指针。