Получение «двойного свободного или поврежденного» только при удалении первого узла связанного списка

#c #linked-list

#c #связанный список

Вопрос:

Цель этой программы — добавить узел в конец связанного списка, который можно удалить с помощью идентификатора.

Я могу удалить каждый узел без проблем, за исключением первого узла. Попытка сделать что-либо после удаления первого узла приводит к неожиданному поведению, такому как полное удаление связанного списка, если я добавляю больше узлов, бесконечный цикл при попытке отобразить данные внутри связанного списка и, или получение ошибки «двойное освобождение или повреждение».

Удаление узла

 struct node* delete_node(struct node *list)

{

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

    printf("nEnter ID: ");
    scanf("%d", amp;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", amp;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 дополнительных узла, связанный список станет чистым, и я смогу выйти без ошибок.

Комментарии:

1. Что ваша функция должна возвращать после удаления первого узла?

2. Извините за поздний ответ, он должен вернуть обновленный связанный список, если это единственный узел в связанном списке, он должен быть нулевым, если я правильно понимаю.

3. Это должно быть, но так ли это?

4. В функции delete_node() указатель prev неинициализирован. Если p не равно NULL, и p->id == id тогда первое, что делается prev , — это присвоение prev->next = p . Даже доступ prev->next (необходимый шаг перед выполнением назначения) дает неопределенное поведение. Это объяснит, почему удаление первого узла завершается неудачей — как только поведение не определено, все ставки в вашей программе отключены.

Ответ №1:

Ваш код удаления не работает должным образом при удалении первого узла в списке. Способ исправить это может быть:

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

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

И temp переменная больше не нужна.

Комментарии:

1. Извините за поздний ответ, я попытался использовать это, и это все та же проблема, я могу удалить каждый узел, кроме первого

2. @IAteYourCat: как вы вызываете delete_node ?

3. delete_node(new_list), в моем основном у меня есть запрос структуры * new_list = NULL;

4. @IAteYourCat: это должно быть new_list = delete_node(new_list) .

5. Это неправильный способ удаления узла в двусвязном списке. Вам необходимо обновить два указателя.