首页 文章

删除链表中的第一个节点仍会在结果中显示节点

提问于
浏览
0

我在删除链表中的第一个节点时遇到了问题,当我删除其他节点成功后打印结果,但删除第一个节点时,它打印0和结构的最后两个成员 .

该函数应该传递一个指向链表的指针,提示用户输入一个ID号以查找删除节点,并返回列表 .

struct dog *delete_from_list(struct dog *dogs){

int num;

    printf("Enter a dogs ID number to be deleted ");
    scanf("%d", &num);

struct dog *prev, *cur;

    for(cur = dogs, prev = NULL;
            cur !=NULL && cur->number != num;
            prev = cur, cur = cur->next);

     if (cur == NULL){

            printf("Dog not found");
            return dogs;
    }
     if( prev == NULL){


            dogs = dogs->next;

            printf("Dog deleted");

    }
     else{

            prev->next = cur->next;
    }


    free(cur);


    return dogs;

}

这是之后打印链表的功能

void print(struct dog *list){

    /* Prints all structs within the
     * linked list
     */


    printf("\nID Number\t Dog Name\t Breed\t\t Owner\n");
    for( ; list != NULL; list = list->next){

            printf("%d\t\t  %-10s\t  %-10s\t %-12s\n", list->number, list->dog_name, list->breed, list->owner_last_name);

    }

}

1 回答

  • 0

    你的功能显然工作正常(修改它接受num作为我的参数...),关于它的实际意图 .

    你没有得到的是输出“狗删除”,如果你不删除头 - 这是因为你没有实现这样做 . 试试这个:

    if (!cur)
    {
        puts("Dog not found");
        return dogs;
    }
    if(!prev)
    {
        dogs = dogs->next;
        puts("head deleted"); // <- changed "dog" -> "head"
    }
    else
    {
        prev->next = cur->next;
        puts("dog deleted"); // <- added by me!
    }
    

    重要的是:你绝对需要这样称呼它(在他的评论中表示为BLUEPIXIY):

    dogs = delete_from_list(dogs);
    

    如果不这样做,你的外部变量'dogs'将不会改变,并指向已经删除的内存 . 如果仍然使用当时的悬空指针,则会出现未定义的行为,很可能是访问冲突(分段错误) .

    为避免出现此类问题,您可能希望将指针传递给指向函数的指针 . 然后,返回值被释放,您可以使用它来指示狗实际上是否已被删除:

    bool // need to #include <stdbool.h> for
    delete_from_list(struct dog** dogs)
    //                          ^
    

    您现在在内部使用 *dogs 而不是 dogs 并将其称为:

    delete_from_list(&dogs);
    

    优势:用户无需关心正确的重新分配......

相关问题