【问题标题】:C Delete Linked List By Reference? [closed]C 按引用删除链表? [关闭]
【发布时间】:2017-04-09 19:42:24
【问题描述】:

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

* `./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;
    }
}

【问题讨论】:

  • 1) while (list) :无限循环。 2) deleteList(&amp;list); showItems(list); --> showItems(list); deleteList(&amp;list);
  • @BLUEPIXY 列表在每次迭代结束时被设置为 &temp->next,最终 temp->next 将 == NULL,从循环中中断....
  • temp-&gt;next 将是 == NULL,但 &amp;temp-&gt;next != NULL
  • while(*list){ temp = *list; *list = temp-&gt;next; free(temp);}(可能是这种预期行为。)
  • C 不支持引用,严格按值传递。

标签: c list linked-list


【解决方案1】:

更好的解决方案如下所示:

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

您的解决方案存储list 指向的节点的地址,然后释放您从未分配过的内容 - 您尝试释放node**,但您只分配nodes。完成此操作后,您然后尝试取消引用您刚刚(排序)尝试释放的内存。

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

【讨论】:

  • 尝试实现您的解决方案,编译器显示“testing.c:100:26: error: member reference base type 'node *' (aka 'struct node *') is not a structure or union”
  • 我稍微编辑了我的答案。这不是一个精确的实现,更多的是作为一些伪代码。它现在应该可以正常工作了。当我写答案时,我忘记了listnode**
  • 没问题!我希望它为什么会这样工作是有道理的。我是数据结构课程的助教,因此如果您需要,我可以更深入地了解它为什么/如何工作。
  • 当您通过引用带有&amp; 运算符的函数传入list 时,您将传递一个指向它的指针(node**)。您必须先取消引用它 ((*list)),然后才能使用 -&gt; 运算符访问其 next 变量。 -&gt; 运算符本身实际上只是简写 - node-&gt;next 等同于 (*node).next(*list)-&gt;next(*(*list)).next 相同。
  • 这可能会发生! &amp; 运算符用于获取某物的地址 - 将其视为 * 运算符的倒数。 &amp; 操作符返回一个指向你调用它的变量的指针; * 运算符取消引用您给它的指针。
【解决方案2】:

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

首先,在函数“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”
  • 调用 free() 后使用内存
  • 你是空闲列表,但这里的指针又是“*list”

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

你可以这样写:

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

【讨论】:

  • 你是对的,但它与上面的克里斯的答案相同。不过,我很感谢你抽出时间来帮助我。其他部分我没有,所以我投票给你。
猜你喜欢
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 2022-11-14
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多