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

问题描述 投票:-1回答:1

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

`

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)

c printing linked-list segmentation-fault
1个回答
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);

您也不会在任何地方释放任何内存,所以我认为您稍后将编写一个函数来清理列表。
© www.soinside.com 2019 - 2024. All rights reserved.