C语言单链表报错Segmentation fault 解决方法

题目就是一个单链表操作的集合,包括链表的建立、删除、插入、打印、释放等操作。

代码在CodeBlocks运行无误,提交到学校的oj平台上就显示段错误。

Segmentation fault 段错误,主要是有有数组越界,指针异常,访问到不应该访问的内存区域。单链表主要涉及的就是指针操作,在检查数组无误(本题未用到)后主要检查指针。

这个是之前的代码:

#include 
#include 

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;
}

排除了其他函数无误后,最后发现错误出现在了最不起眼的 释放链表函数中,发现是 while循环 结束标志有误,head总是比p指针快一步,如果以p!=NULL为循环结束标志的话,在head所指向的已经为NULL,p指向最后一个节点时,完成循环,p所指向的节点被释放,此时p还不是NULL,所以循环还得继续,head就得向后再移动,此时head指针就成了野指针,无所指向,故会报错。

修改后将while循环结束标志换位head!=NULL,会在p指向最后一个节点,head为空时,释放p所指向的节点,循环结束,不会造成野指针的现象。

修改后的 释放单链表函数 为:

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

修改后再次提交到oj平台,正确通过。

你可能感兴趣的:(c语言,单链表,数据结构)