C通过引用删除链接列表?

时间:2017-04-09 19:42:24

标签: c list linked-list

全新的C,在发布之前尝试了我发现的其他SO答案,并看到他们都没有使用函数并通过引用传递他们的列表以删除所有项目,但这是我想要的方式实现它。控制台正在输出

  

*`./testing':双重免费或损坏(输出)错误:0x00007ffc26622b30 * 已中止

菜鸟的真棒错误消息!这根本就不神秘。 :)
附:我的所有其他功能都按预期工作。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct node
{
    int n;
    struct node* next;
} 
node;

bool search(int number, node* list);
void showItems(node* list);
void insertItem(int number, node** list);
void deleteItem(int number, node** list);
void deleteList(node** list);

int main(void)
{

    node* list = NULL;

    insertItem(1337, &list);
    insertItem(1337, &list);

    bool found = search(5, list);
    if (found)
    {
        printf("found number in linked list.");
    }

    deleteList(&list);

    showItems(list);
}

void showItems(node* list)
{
    node* ptr = list;
    while (ptr)
    {
        printf("%i\n",ptr->n);
        ptr = ptr->next;
    }
}

bool search(int number, node* list)
{
    node* ptr = list;
    while (ptr)
    {
        if (ptr->n == number)
        {
            return true;
        }
        ptr = ptr->next;

    }
    //Number not found.
    return false;
}

void insertItem(int number, node** list)
{
    node* newItem = malloc(sizeof(node));
    newItem->n = number;
    newItem->next = *list;
    *list = newItem;
}

void deleteItem(int number, node** list)
{

    node* ptr = *list;
    node* prev = NULL;

    while (ptr)
    {
        if (ptr->n == number)
        {
            if (prev != NULL)
            {
                //Check if there is a previous node.  If there is, set its next node to the current items next node.  Then free the current node.
                prev->next = ptr->next;

            }
            free(ptr);
            break;
        }
        prev = ptr;
        ptr = ptr->next;
    }
}

void deleteList(node** list)
{
    node* temp = NULL;
    while (list)
    {
        temp = *list;
        free(list);
        list = &temp->next;
    }
}

2 个答案:

答案 0 :(得分:4)

更好的解决方案看起来像这样:

while(*list) {
  node* tmp = (*list)->next;
  free(*list);
  *list = tmp;
}

您的解决方案存储list指向的节点的地址,然后释放您从未分配的内容 - 您尝试释放node**,但只分配node s 。在这之后,您尝试取消引用刚才(sorta)试图释放的内存。

您需要存储指向下一个节点的指针,释放当前节点,然后移动到下一个节点。

答案 1 :(得分:1)

对于菜鸟来说,这是一个很好的编码。但我看到了一些缺陷。

首先,在函数“deleteItem”中检查是否(prev!= NULL)但是当它为NULL时你什么都不做。你必须更新* list。

    if (prev != NULL)
    {
        //Check if there is a previous node.  If there is, set its next node to the current items next node.  Then free the current node.
        prev->next = ptr->next;
    } 
    else // you have to add an else here
    {
        *list = ptr->next;
    }

然后,在函数“deleteList”中,我看到三个错误。

  • 您测试列表,但“list”是指针上的指针。指针是“* list”
  • 在调用free()
  • 后使用内存
  • 你有空闲列表,但这里的指针又是“* list”

    node* temp = NULL;
    while (list)
    {
        temp = *list;
        free(list);
        list = &temp->next;
    }
    

你可以这样写:

    while (*list)
    {
        node *temp = (*list)->next;
        free(*list);
        *list = temp;
    }