Удаление связанного списка в C - PullRequest
0 голосов
/ 10 декабря 2011

Я пытаюсь создать функцию, которая удаляет весь список, но я получаю сообщение об ошибке. Все работает, кроме функции cleaner ().

#include <stdio.h>
#include <stdlib.h>

struct node{
    int n;
    struct node *next;
};

typedef struct node NOD;

NOD *create_first_node(int i)
{
    NOD *q;
    q=(NOD*)malloc(sizeof(NOD*));
    q->n=i;
    q->next=NULL;
    return q;
}

NOD * add_to(NOD *x)
{
    NOD *q;
    q=(NOD*)malloc(sizeof(NOD*));
    q->n=rand();
    x->next=q;
    q->next=NULL;
    return q;
}

void show_list(NOD *p)
{
    printf("root");
    while(p->next){
        printf(" -> %d",p->n);
        p=p->next;
    }
    printf("\n");
}


void cleaner(NOD *p)
{
    NOD *r;
    while(p)
    {
        r=p;
        p=r->next;
        free(r);
        r=NULL;
    }
}


int main()
{
    int i;
    NOD *root,*c,*r;
    root=create_first_node(1);
    c=r=root;
    c=add_to(root);
    for(i=0;i<10;i++)
    {
        r=c;
        c=add_to(r);
    }
    show_list(root);
    //cleaner(root);
    system("pause");
    return 0;
}

NetBeans:

Получен сигнал: SIGTRAP (?) С sigcode? (?) Из процесса: Для списка программ pid -1

Вы можете отказаться от сигнала или переслать его, и вы можете продолжить или приостановить процесс Чтобы контролировать, какие сигналы перехватываются или игнорируются, используйте Debug-> Dbx Configure


Visual Studio:

Ошибка отладки!

ОБНАРУЖЕНА КОРРУПЦИЯ КАРТЫ: после блока Normal (# 57) в 0x00393230 CRC обнаружил, что приложение записало в память после завершения буфера кучи.

(Я получаю эту ошибку с # 57, # 58, ..., # 68 каждый раз, когда cleaner () пытается освободить элемент списка)

Ответы [ 3 ]

3 голосов
/ 10 декабря 2011

q=(NOD*)malloc(sizeof(NOD*)); должно быть q=(NOD*)malloc(sizeof(NOD));, я думаю.

Вам необходимо выделить достаточно памяти для всего узла, но вы только выделяете достаточно для указателя на него.

1 голос
/ 10 декабря 2011

Я признаю, что только что просмотрел ваш код, но когда вы создаете и добавляете узлы, вы делаете

 q=(NOD*)malloc(sizeof(NOD*));

но на самом деле вы должны сделать

 q=(NOD*)malloc(sizeof(NOD));

В противном случае вы просто выделите место для NOD *, которое составляет 4 или 8 байт в зависимости от вашей системы (и предполагается, что это обычный ПК). Но ваша структура NOD будет иметь по крайней мере 8 или 16 байтов (опять же, в зависимости от вашей системы и размера вашего int и предполагается, что вы используете обычное оборудование ПК).

Поэтому, когда вы получаете доступ к члену n , вы уже находитесь на легальном основании, но когда вы позже прикасаетесь к члену next , вы находитесь в середине неопределенного поведения и вам повезло Ваше программное обеспечение вызывает только повреждение кучи ...

0 голосов
/ 10 декабря 2011
  • NULL это не обязательно то же самое, что 0. Это обычно , но вы "не должны" предполагать, что это будет.Итак, while(p) опасно ... используйте while (NULL != p) или (p != NULL): -)
  • При использовании malloc вы выделяете размер NOD*, указатель;вы намеревались использовать sizeof(NOD).
  • Кроме того, не добавляйте типьный перевод (NOD*) при возврате malloc.(Google "malloc typecast" для подробного списка причин, но достаточно сказать, что это бесполезно и, скорее всего, сломать ваш код и спрятать ошибки позже.)
  • r = NULL излишне, но это хорошопривычка проникать, очищать указатель после free(), так что это неплохо: -)
...