我知道这回答了很多次,但我无法弄清楚出了什么问题。
我有一个结构
typedef struct zaznam{
char kategoria[53];
char znacka[53];
char predajca[103];
double cena;
int rok;
char stav[203];
struct zaznam *next;
}ZAZNAM;
我想以这种方式删除第一个节点。
for(prev = act = prvy; act!=NULL; prev=act, act=act->next){
if((strstr(act->znacka,vyber)!=NULL)){
if(act->znacka==prvy->znacka){
//if "znacka" of the actual node is equal to the first
prev=prvy->next; //in "previous" is pointer to the second node
free((void *)act); //free first node
prvy=prev; //first node = previous
}
else{ //this works
prev->next=act->next;
free((void *)act);
act=prev;
}
它适用于所有内容,但不适用于第一个节点。
答案 0 :(得分:1)
嗯,你刚开始违反自己的不变prev->next == act
:for (prev = act = prvy;...
其次,act->znacka==prvy->znacka
act==prvy
应该是act==prev
,以确定您是否处于链接的开头,否则会让人感到困惑。
我可能会尝试通过为第一种情况添加act=prev;
来重新开始(但错误的)不变量({{1}})。也许它会起作用。
答案 1 :(得分:0)
在我看来,当你继续prev
- 循环的下一次迭代时,当你删除第一个节点时,你没有正确地指定for
指向下一个节点。例如,在第一个if
语句中检查您是否在第一个节点,执行以下操作:
prev=prvy->next; //in "previous" is pointer to the second node
free((void *)act); //free first node
prvy=prev; //first node = previous
这会释放第一个节点,但是,在您的for
- 循环中,您可以在此处act
分配prev
:
for(prev = act = prvy; act!=NULL; prev=act, act=act->next)
由于释放内存实际上并不会擦除内存内容,因此继续执行列表的其余部分,就好像第一个节点尚未释放一样。实际上使用像这样的释放指针是未定义的行为,所以任何事情都可能发生(即你可能会崩溃等等......在这种情况下,你似乎不是这样)。
尝试将代码更改为以下内容:
for(prev = act = prvy; act!=NULL;)
{
if((strstr(act->znacka,vyber)!=NULL))
{
if(act==prvy)
{
//we're at the first node
ZAZNAM* temp=act->next;
free((void *)act); //free first node
prev=act=prvy=temp; //re-establish starting condition
}
else
{
prev->next=act->next;
free((void *)act);
act=prev->next;
}
}
else
{
//iterate here because if you delete the first node, you don't want
//to start iterating like would happen if you kept iteration in the
//for-loop declaration
prev=act;
act=act->next;
}
}