Удалить односвязный список со структурными элементами - PullRequest
0 голосов
/ 04 июня 2019

В настоящее время я застрял с заданием в моем текущем назначении, и я понятия не имею, почему он делает то, что делает, а не то, что я хочу.

Прежде всего, вот задание:

Предоставляется односвязный список, который определяется как:

typedef struct { 
    char lastname[30]; 
    char firstname[30]; 
} person_t;
typedef struct perslistelement { 
    person_t pers_obj; 
    struct perslistelement *next; } PersListElement;

a) Напишите функцию void printPerson (person_t pers) для отображения объект person_t.

б) Написать функцию void printPersList (PersListElement * p), который отображает каждого человека в список. Используйте функцию printPerson ()

в) Написать рекурсивную функцию void printReversePersList (PersListElement * p), который отображает каждый Спасенный человек в обратном порядке. То есть человек, который был спасен последним должен отображаться первым и т. д. Используйте функцию printPerson ()

d) Напишите функцию void deletePersList (PersListElement * p), которая удаляет список.

e) Проверьте свои функции с помощью следующей программы:

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

typedef struct {
    char lastname[30];
    char firstname[30];
} person_t;

typedef struct perslistelement {
    person_t pers_obj;
    struct perslistelement *next;
} PersListElement;

PersListElement *insertPerson(PersListElement *first, char lastname[], char firstname[]){

    PersListElement *p;
    p = (PersListElement*)malloc(sizeof(PersListElement));
    strcpy(p->pers_obj.lastname, lastname);
    strcpy(p->pers_obj.firstname, firstname);
    p->next = first;
    first = p;
    return first;

}


/* Insert functions from a ) , b ) , c ) and d) ! */


int main(void){

    PersListElement *p = NULL;
    printf("Test Program : Assignment 8 / Task 1");

    printf(" Step 1: Building the list \n" );
    p = insertPerson(p, "Banner", "Bruce");
    p = insertPerson(p, "Stark", "Tony");

    printf("\nStep 2: Printing the list\n");
    printPersList(p);

    printf("\nStep 3: Printing the list in reverse order\n");
    printReversePersList(p);

    printf("\nStep 4: Deleting the list\n");
    deletePersList(p);

    return 0;
}

У меня не было проблем с назначением a к c. Функции, которые я написал, работают отлично и делают то, что должны. Однако по какой-то причине последняя функция, где я должен удалить список, удаляет только часть фамилии элементов списка. По крайней мере, когда я использую функцию printPersList после использования функции удаления, она отображает фамилии как mumbo-jumbo, в то время как имена остаются неизменными.

Вот как это выглядит:

См. Прикрепленное изображение

Вот функции, которые я написал:

а)

void printPerson(person_t pers){

    printf("Last Name: %s \nFirst Name: %s\n\n", pers.lastname,pers.firstname);

}

б)

void printPersList(PersListElement *p){

    while(p != NULL) {
        printPerson(p->pers_obj);
        p = p->next;
    }
}

с)

void printReversePersList(PersListElement *p){

    if (p == NULL) return;
    printReversePersList(p->next);
    printPerson(p->pers_obj);
}
* 1 039 * г)
void deletePersList(PersListElement *p){

    while(p != NULL) {
        free(p);
        p = p->next;
    }
}

Может кто-нибудь объяснить мне, в чем была ошибка и как ее исправить?

Также, пожалуйста, имейте в виду, что я перевел все это назначение с немецкого на английский только для stackoverflow, поэтому, если есть какие-то другие ошибки где-либо за пределами функции deletePersList, игнорируйте это, пожалуйста, так как это, вероятно, я просто упустил из виду при переводе все.

1 Ответ

2 голосов
/ 04 июня 2019

Вы освобождаете p, а затем используете p, что является неопределенным поведением.Вам нужно получить p->next и сохранить его во временной переменной или в чем-то до освобождения p

void deletePersList(PersListElement *p){

    while(p != NULL) {
        free(p);
        p = p->next; // this is undefined
    }
}

Решение может быть

void deletePersList(PersListElement *p){
    while(p != NULL) {
        PersListElement *next = p->next;
        free(p);
        p = next; 
    }
}
...