2015-04-08 7 views
2

Кто-нибудь знает, что не так с этой рекрусирующей функцией? Он не удаляет все узлыудаление всех узлов в связанном списке

struct contact 
{ 
    char FirstName[41]; 
    char LastName[41]; 
    int id; 
    struct contact *next; 
}; 

void ClearList (struct contact *person) 
{ 
    struct contact *temp = person; 
    if (person == NULL) return; 
    else 
    { 
     person = person->next; 
     free(temp); 
     ClearList(person); 
    } 
} 

это моя главная функция

void main() 
{ 
    struct contact *person = malloc(sizeof(struct contact)); 
    strcpy (person->FirstName, "John"); 
    strcpy (person->LastName, "Doe"); 
    person->id = 10; 

    person->next = malloc(sizeof(struct contact)); 
    strcpy (person->next->FirstName, "Will"); 
    strcpy (person->next->LastName, "Smith"); 
    person->next->id = 20; 
    person->next->next = NULL; 

    PrintList(person); 
    ClearList(person); 
    PrintList(person); 
} 

, когда я звоню после вызова перечень печати ClearList он все еще печатает несколько беспорядочных питания, как это исправить?

+0

Каково определение 'struct contact'? – horns

+1

Вы пробовали переходить через код по строкам в отладчике? И как вы знаете, что он не удаляет все узлы? –

+5

'void ClearList (struct contact * person) {if (person) {ClearList (person-> next); free (person);}' – BLUEPIXY

ответ

4

Все узлы are удалены, но вы никогда не очищаете указатели. Итак, что вы делаете, это разыменование недействительных указателей, приводящих к undefined behavior.

Функция free не устанавливает автоматически указатели на NULL.

+0

так что я должен положить temp = NULL? –

+0

По крайней мере, это не было бы вредно. – dhein

+0

Я думаю, что вы должны установить 'person' внутри main() в NULL после того, как вы сделаете' Clearlist (person); ' – Raj

2

Мне действительно не нравится это рекурсивное удаление в вашем связанном списке. Если ваш связанный список содержит 100 элементов, вы пойдете на 100 функций в глубину вашего стека и, возможно, сработаете.

Я предлагаю переписать так:

void ClearList (struct contact *person) 
{ 
    while(person != NULL) 
    { 
     struct contact * temp = person 
     person = person->next; 
     free(temp); 
    } 
} 

Joachim имеет правильный ответ, хотя. Хотя мы очистили память, на которую указывает человек, «ClearList» не имеет права устанавливать исходный указатель на NULL. Поэтому либо вы должны сделать ClearList взять двойной указатель, чтобы он мог установить указатель на NULL, либо просто установить «человек» в NULL после вызова ClearList.

Пример с двумя указателями, вызов с помощью ClearList (& человек);

void ClearList (struct contact ** list) 
{ 
    struct contact *person = *list; 
    while(person != NULL) 
    { 
     struct contact * temp = person 
     person = person->next; 
     free(temp); 
    } 
    *list = NULL; 
} 
Смежные вопросы