题目就是一个单链表操作的集合,包括链表的建立、删除、插入、打印、释放等操作。
代码在CodeBlocks运行无误,提交到学校的oj平台上就显示段错误。
Segmentation fault 段错误,主要是有有数组越界,指针异常,访问到不应该访问的内存区域。单链表主要涉及的就是指针操作,在检查数组无误(本题未用到)后主要检查指针。
这个是之前的代码:
#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;
}
排除了其他函数无误后,最后发现错误出现在了最不起眼的 释放链表函数中,发现是 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平台,正确通过。