删除C中链表中的第一个节点

时间:2012-12-01 18:25:12

标签: c linked-list

我知道这回答了很多次,但我无法弄清楚出了什么问题。

我有一个结构

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

它适用于所有内容,但不适用于第一个节点。

2 个答案:

答案 0 :(得分:1)

嗯,你刚开始违反自己的不变prev->next == actfor (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;
    }
}