打印链表时如何解决分段错误?

时间:2019-11-06 14:59:36

标签: c printing linked-list segmentation-fault

当尝试打印我的学生的链表时,出现“细分错误(核心被弃用)”的提示。当我通过硬编码打印列表时:

`

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){...}

我尝试在main中进行此操作,而不是调用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 个答案:

答案 0 :(得分:1)

使用这种代码的方式,列表上的最后一个节点将指向您第一次使用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;
}