按特定标准删除链表的元素

时间:2015-06-01 15:58:49

标签: c

我写过这个函数:

List* delPaintingCode(List* head, char *code)
{
    List *p,*q;

    for(p=head;p!=NULL;q=p,p=p->next)
    {
        if(!strcmp(code,p->code))
        {
            if (p==head)
            {
                q=head;
                head=p->next;
                free(q);
            }
            else
            {
                q->next=p->next;
                free(p);
                p=q;
            }
        }
    }
    return head;
}

当我在另一个函数中调用它时:

void delpainting()
{ 
    char code[50];
    printf("code ");
    scanf("%s",code);

    List *head=NULL;

    head=delPaintingCode(filetolist,code);
}

程序崩溃了。我有一个警告:passing argument 1 of delPaintingCode from incompatible pointer type

那么我应该如何将字符串传递给函数?

1 个答案:

答案 0 :(得分:1)

导致崩溃的逻辑问题出现在代码的if (p==head)分支中:当您删除初始元素时,释放head而不更新p。这导致在下一次迭代时取消引用释放的指针。

您可以通过在head中引入next的假节点并返回next来修复此问题,如下所示:

List fake;
fake.next = head;
// This loop always looks ahead by one element, i.e. at p->next.
for(List *p = &fake ; p->next != NULL ; p = p->next) {
    if(strcmp(code, p->next->code)) {
        continue;
    }
    List *q = p->next;
    p->next = q->next;
    free(q);
}
return fake.next;

这种方法也适用于初始元素,因为我们在列表中添加了一个假头,因此第一次p->next与head相同。这让我们统一了头元素和所有其他元素的处理。