到目前为止,我已经编写了这段代码。这是我的结构,但我真正使用的是这个函数中的平均场。
struct grade
{
char *crs;
int grd;
};
struct student
{
char *name;
int yr;
struct grade grades[3];
float avg;
struct student *nxt;
}*root;
现在这是相应的函数,在调用时会导致分段错误。
void delete_failed()
{
struct student *i=root;
for (;i->nxt!=NULL;i=i->nxt);
if (i->nxt->avg<5.00)
{
struct student *j=i->nxt;
i->nxt=i->nxt->nxt;
free(j);
delete_failed();
}
}
答案 0 :(得分:1)
您的功能存在许多问题。首先,for循环检查i->nxt
不是NULL。如果列表为空怎么办?这会使i
为NULL并导致崩溃。
其次,for循环跳过大部分列表直到最后一个元素(即i->nxt
为NULL时),这似乎并不特别有用。特别是当您开始使用i->nxt
做NULL时。
所以在任何一种情况下,你的功能都会崩溃。
这是修订版......
void delete_failed()
{
struct student *i,*last=NULL,*next_i;
for (i=root;i!=NULL;i=next_i)
{
next_i=i->nxt;
if (i->avg<5.00)
{
if(last)
{
last->nxt=i->nxt;
}
else
{
root = i->nxt;
}
if(i->name) free(i->name);
free(i);
}
}
else
{
last=i;
}
}
}
root
,或者可以将last->nxt
指向i->nxt
。在执行任何其他操作之前,它会在i->nxt
中保留next_i
的副本,以便它可以使用它来更新i
以进行下一次循环迭代。
它还会释放原先未包含的i->name
,并且需要将其视为char *
答案 1 :(得分:0)
我不确定你要做什么,但是......
for (;i->nxt !=NULL;i=i->nxt);
这会将i
增加到i == NULL
。
然后,在该循环之后的代码中,您尝试取消引用i
并使用它的值,这是未定义的行为,因此您会遇到段错误。
也许你的意思是:
for (;i->nxt!=NULL;i=i->nxt)
{
if (i->nxt->avg<5.00)
{
struct student *j=i->nxt;
i->nxt=i->nxt->nxt;
free(j);
delete_failed();
}
}