Solution to the segmentation fault of single chain table in C language

The title is a collection of single linked list operations, including the establishment, deletion, insertion, printing, release and other operations of linked list.

The code runs correctly in CodeBlocks, and an error is displayed when it is submitted to the OJ platform of the school.

The segmentation fault section is wrong, mainly because the array is out of bounds, the pointer is abnormal, and the memory area that should not be accessed is accessed. Single linked list mainly involves pointer operation. After checking that the array is correct (not used in this topic), it mainly checks the pointer.

This is the previous code:

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

typedef struct student
{
    long int num;
    float score;
    struct student *next;
}Node,*Link;

Link creatlink(void)
{
    Link head,node,rear;
    long int p;
    float q;
    head = (Link)malloc(sizeof(Node));
    head -> next = NULL;
    rear = head;
    while(scanf("%ld %f",&p,&q))
    {
        if(p == 0&&q == 0)
        {
            break;
        }
        node = (Link)malloc(sizeof(Node));
        node -> num = p;
        node -> score = q;
        rear -> next = node;
        rear = node;
    }
    rear -> next = NULL;
    return head;
}

void printlink(struct student *head)
{
    Link p;
    p = head -> next;
    while(p != NULL)
    {
        printf("%ld %.2f\n",p -> num,p -> score);
        p = p -> next;
    }
}

Link dellink(Link head,long int k)
{
    if(head == NULL||head -> next == NULL)
        exit(0);
    Link p,q;
    p = head -> next;
    q = head;
    while(p != NULL)
    {
        if(p -> num == k)
        {
            q -> next = p -> next;
            free(p);
        }
        else
        {
            q = p;
            p = p -> next;
        }
    }
    return head;
}

Link insertlink(Link head,Link stu)
{
    Link p,node,q;
    p = head;
    q = p -> next;
    while(q != NULL&&q -> num < stu -> num)
    {
        p = p -> next;
        q = p -> next;
    }
    if(q == NULL)
        p -> next = NULL;
    node = (Link)malloc(sizeof(Node));
    node -> num = stu -> num;
    node -> score = stu -> score;
    node -> next = p -> next;
    p -> next = node;
    return head;
}

void freelink(Link head)
{
    Link p;
    while(p != NULL)
    {
        p = head;
        head = head -> next;
        free(p);
    }
}

int main()
{
    struct student *createlink(void);
    struct student *dellink(struct student *, long);
    struct student *insertlink(struct student *, struct student *);
    void printlink(struct student *);
    void freelink(struct student *);
    struct student *head, stu;
    long del_num;
    head= creatlink();
    scanf("%ld", &del_num);
    head= dellink(head, del_num);
    scanf("%ld%f", &stu.num, &stu.score);
    head= insertlink(head, &stu);
    scanf("%ld%f", &stu.num, &stu.score);
    head= insertlink(head, &stu);
    printlink(head);
    freelink(head);
    return 0;
}

After excluding the error of other functions, it is finally found that the error occurs in the most insignificant release linked list function. It is found that the while loop end flag is wrong, and the head is always one step faster than the P pointer. If P= If NULL is the loop end flag, the loop is completed when the point pointed by the head is null and P points to the last node. At this time, P is not null, so the loop has to continue and the head has to move back. At this time, the head pointer becomes a wild pointer and has no point, so an error will be reported.

After modification, transpose the while loop end flag to head= Null, when p points to the last node and head is null, the node pointed to by P will be released, and the loop will end without wild pointer.

The modified release single linked list function is:

void freelink(Link head)
{
    Link p;
    while(head != NULL)
    {
        p = head;
        head = p -> next;
        free(p);
    }
}

After modification, submit it to OJ platform again and pass it correctly.


Read More: