Как исправить ошибку сегментации при печати связанного списка? - PullRequest
0 голосов
/ 06 ноября 2019

Когда я пытаюсь распечатать свой связанный список студентов, мне выдается «Ошибка сегментации (ядро сброшено)». Когда я печатаю список жестким кодированием:

`

for (i = 0; i < 3; i++){
    printf("%s, %s\n", head->pStudent->last, head->pStudent->first);
    head = head->next;
}

`

(создано 3 узла). Это работает! Когда я пытаюсь напечатать это так:

`

while (head != NULL){
    printf("%s, %s\n", head->pStudent->last, head->pStudent->first);
    head = head->next;
}

`

Это дает мне ошибку сегментации.

Я пробовал while (head->next != NULL){...}

Я пытался сделать это в основном вместо вызова print_list(head);


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

    typedef struct student{
        char *first;
        char *last;
    } student_t;

    typedef struct node{
        student_t *pStudent;
        struct node *next;
    } node_t;

    void addToStart(node_t ** head, student_t *student);
    void print_list (node_t * head);
    student_t *newStudent();

    int main(){
        node_t *head;
        student_t *studentOne = (student_t *) malloc(sizeof(student_t));
        student_t *studentTwo = (student_t *) malloc(sizeof(student_t));
        student_t *studentThree = (student_t *) malloc(sizeof(student_t));

        studentOne->first = (char *) malloc(sizeof(char));
        studentOne->last = (char *) malloc(sizeof(char));

        studentTwo->first = (char *) malloc(sizeof(char));
        studentTwo->last = (char *) malloc(sizeof(char));

        studentThree->first = (char *) malloc(sizeof(char));
        studentThree->last = (char *) malloc(sizeof(char));

        studentOne = newStudent();
        addToStart(&head, studentOne);

        studentTwo = newStudent();
        addToStart(&head, studentTwo);

        studentThree = newStudent();
        addToStart(&head, studentThree);

        print_list(head);

        printf("Then you will enter 3 students names that will be added to the end of the list\n");

        return 0;
    }

    void addToStart(node_t ** head, student_t *student){
        node_t *new = (node_t *) malloc(sizeof(node_t));

        new->pStudent = student;

        new->next = *(head);
        *(head) = new;
    }

    void print_list (node_t * head){
        while (head != NULL){
            printf("%s, %s\n", head->pStudent->last, head->pStudent->first);

            head = head->next;
        }

    }

    student_t *newStudent(){
        student_t *new = (student_t *) malloc(sizeof(student_t));
        new->first = (char *) malloc(sizeof(char));
        new->last = (char *) malloc(sizeof(char));

        printf("Enter first name of student: ");
        scanf("%s", new->first);
        printf("Enter last name of student: ");
        scanf("%s", new->last);

        return new;
    }

Ожидаемые результаты:


    Enter first name of student: 1
    Enter last name of student: 1
    Enter first name of student: 2
    Enter last name of student: 2
    Enter first name of student: 3
    Enter last name of student: 3
    3, 3
    2, 2
    1, 1

Фактические результаты:


    Enter first name of student: 1
    Enter last name of student: 1
    Enter first name of student: 2
    Enter last name of student: 2
    Enter first name of student: 3
    Enter last name of student: 3
    3, 3
    2, 2
    1, 1
    Segmentation fault (core dumped)

1 Ответ

1 голос
/ 06 ноября 2019

Как у вас есть этот код, последний узел в списке будет указывать на то, что у вас есть переменная head, как при первом выполнении addToStart. Но head не инициализируется:

node_t *head;

Правильно инициализируйте его, чтобы цикл завершился правильно:

node_t *head = NULL;

У вас также есть только 1 char памяти для ваших строк,Этого не достаточно ни для чего, кроме пустой строки. Попробуйте вместо этого:

new->first = malloc(32); // memory for 31 chars plus null terminator
new->last = malloc(32);

printf("Enter first name of student: ");
scanf("%31s", new->first); // read a maximum of 31 chars
printf("Enter last name of student: ");
scanf("%31s", new->last);

Более того, вы выделяете память для учеников и строк дважды, в процессе чего происходит утечка памяти. Удалите эти избыточности и сделайте это вместо этого:

student_t *studentOne = newStudent();
student_t *studentTwo = newStudent();
student_t *studentThree = newStudent();

addToStart(&head, studentOne);
addToStart(&head, studentTwo);
addToStart(&head, studentThree);

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

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

typedef struct student {
    char *first;
    char *last;
} student_t;

typedef struct node {
    student_t *pStudent;
    struct node *next;
} node_t;

void addToStart(node_t ** head, student_t *student);
void print_list(node_t * head);
student_t *newStudent();

int main() {
    node_t *head = NULL;
    student_t *studentOne = newStudent();
    student_t *studentTwo = newStudent();
    student_t *studentThree = newStudent();

    addToStart(&head, studentOne);
    addToStart(&head, studentTwo);
    addToStart(&head, studentThree);

    print_list(head);

    printf("Then you will enter 3 students names that will be added to the end of the list\n");

    return 0;
}

void addToStart(node_t ** head, student_t *student) {
    node_t *new = (node_t *)malloc(sizeof(node_t));

    new->pStudent = student;

    new->next = *(head);
    *(head) = new;
}

void print_list(node_t * head) {
    while (head != NULL) {
        printf("%s, %s\n", head->pStudent->last, head->pStudent->first);

        head = head->next;
    }

}

student_t *newStudent() {
    student_t *new = (student_t *)malloc(sizeof(student_t));
    new->first = (char *)malloc(32);
    new->last = (char *)malloc(32);

    printf("Enter first name of student: ");
    scanf("%31s", new->first);
    printf("Enter last name of student: ");
    scanf("%31s", new->last);

    return new;
}
...