【问题标题】:C: removing linked listC:删除链表
【发布时间】:2018-09-03 19:44:25
【问题描述】:

我有以下结构的链表:

struct pomiar {
    unsigned int nr_pomiaru;
    unsigned int nr_czujnika;
    char data_i_czas[20];
    double temp;
    struct pomiar *nast;
};

我使用malloc() 分配所有元素:每个元素都由前一个元素指向。

释放列表时,我是否应该遍历整个列表并释放 *nast 指向最后一个,或者我到底应该怎么做?

【问题讨论】:

  • 你的链表是如何实现的?这有点相关?
  • @AlexanderHuszagh 我编辑了我的问题,希望它能回答你的问题。
  • 是的,您应该遍历列表,为当前元素获取nast 指针的副本,然后释放当前元素,然后将复制的nast 值放入当前元素中。在内存空闲后,您无法(可靠地)访问内存——不要!因此复制。 void free_list(struct pomiar *list) { while (list != NULL) { struct pomiar *nast = list->nast; free(list); list = nast; } }
  • @JonathanLeffler 谢谢你,这回答了我的问题。

标签: c list linked-list free singly-linked-list


【解决方案1】:

是的,您应该遍历列表,为当前元素获取nast 指针的副本,然后释放当前元素,然后将复制的nast 值放入当前元素中。在内存空闲后,您无法(可靠地)访问内存——不要!因此,复制。

void free_list(struct pomiar *list)
{
    while (list != NULL)
    {
        struct pomiar *nast = list->nast;
        free(list);
        list = nast;
    }
}

【讨论】:

  • 您的方法,就像其他答案中的方法一样,仅用于释放一个列表。我有五个,没有任何联系。当我尝试释放一个列表(其中任何一个)时,它可以工作。当我想释放第一个然后第二个时,它仅适用于第一个,第二个会产生错误“有效堆指针”。当我想释放第二个然后第一个 - 第二个被释放,但第一个产生提到的错误。为什么会这样?
  • "CrtIsValidHeapPointer (pUserData)" 准确地说。
  • 我们需要了解您是如何创建其他列表的,但是对于单独的列表共享数据没有明显的方法。您可以将一个列表作为另一个列表的后缀;如果你没有特别小心,你最终会释放已经释放的内存。但这有点不太可能。
  • 我认为"CrtIsValidHeapPointer (pUserData)" 表示您在 MS Windows 上运行并使用 C 运行时 (CRT) 和 CrtIsValidHeapPointer 检查堆指针是否有效并触发断言或类似的东西如果指针无效。至少,它是这样的。正如我所说,我们需要查看创建列表的代码(或者,至少,一个 2 列表 MCVE — minimal reproducible example — 代码的版本)。如果列表是独立的,则应该没有问题。如果它们以某种方式连接,则可能(将会)出现问题。但很难猜出你有什么。
  • 好吧哇,我不知道你评论的第一部分是什么意思。我将尝试通过代码并绘制所有内容以查看实际发生的情况。程序的其他部分按照它们应该的方式工作,我认为这几乎是不可能的,如果列表以某种方式连接。
【解决方案2】:

是的。为了释放列表,您必须遍历整个列表并显式释放每个节点。

void list_free(struct pomiar *head)
{
    struct pomiar *tmp = head;
    while(head)
    {
        head = head->next;
        free(tmp);
        tmp = head;
    }
}

【讨论】:

    【解决方案3】:

    您需要为列表的节点释放所有分配的内存。

    如果支持该列表的声明类似于

    struct pomiar *head = NULL;
    

    那么函数可以看下例如下面的方式。

    void free_list( struct pomiar **head )
    {
        while ( *head )
        {
            struct pomiar *tmp = *head;
            *head = ( *head )->nast;
            free( tmp );
        }
    }
    

    并像这样称呼

    free_list( &head );
    

    在这种情况下,原来的head在退出函数后将等于NULL,可以作为空列表重新使用。

    【讨论】:

      【解决方案4】:

      链表是一种不同于数组非连续内存位置的数据结构。这就是你必须遍历整个链表的原因。如果它是一个数组,你只需要一个指向第一个元素的指针,然后调用 free 就可以了,因为在数组中 它是连续的内存位置。

      【讨论】:

        猜你喜欢
        • 2018-10-14
        • 2019-05-10
        • 2021-07-25
        • 2012-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多