【问题标题】:Regarding freeing nodes while deleting them from Linked List关于从链接列表中删除节点时释放节点
【发布时间】:2014-02-25 00:08:30
【问题描述】:

以下是删除链表中重复元素的功能

void deleteDup(Node *head)
{
    Node *ptr1, *ptr2, *prev;

    for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next){

        prev = ptr1;

        for (ptr2 = ptr1->next; ptr2 != NULL; prev = ptr2, ptr2 = ptr2->next){
            if (ptr1->value == ptr2->value){
                prev->next = ptr2->next;
                free(ptr2);    // Question 1
            }
        }
    }    
}

问题 1: 以上代码适用于 (1->1->2->3->1)。但是写完之后,我自己也糊涂了。

困惑:当它释放 ptr2 时,它是如何在循环中向前移动的?释放 ptr2 后,prev = ptr2, ptr2 = ptr2->next 不应该出现 seg 错误吗?

问题 2: 这段代码可以优化吗? (即节省资源或提高性能)

【问题讨论】:

  • @Jonathon 一般问题:我们如何在提问时快速格式化代码。我总是被 > 或 4 个空格方法卡住
  • 选择代码并点击{ }按钮。我也手动修复了一些缩进。

标签: c linked-list free


【解决方案1】:

问题 1:
确实有问题。一般来说,您必须期待未定义的行为
(可以,但不一定是段错误。
也可以无错误地运行,但只有“可以”,不会。

for (ptr2 = ptr1->next; ptr2 != NULL;){
    if (ptr1->value == ptr2->value){
        prev->next = ptr2->next;
        free(ptr2);    // Question 1
    }
    else prev = ptr2;
    ptr2 = prev->next;
}

应该这样做(也许。我累了。)

问题 2:最佳内存优化:
用它的指针摆脱列表并使用数组:p
时间选择:太。其他数据结构更适合这样的事情。
如果您愿意在此过程中增加内存,
迭代列表并将每个元素插入到不同的数据事物中,例如某种树
在那里你可以很容易地检查一个元素之前是否出现过
(并在仅此一次迭代期间将其从列表中删除)

【讨论】:

  • 我很欣赏你的回答(1 票是我的 :)),但为什么上面仍然有效,可能是什么确切原因,这意味着免费是无用的还是什么?
  • 不,免费不是没用的。 free 的作用:告诉操作系统这个内存是空闲的,可以分配给另一个新的调用或另一个程序。什么免费没有:用其他东西覆盖内存内容。就您而言,您很幸运,内容在免费和最后一次访问之间没有变化。 (或者“不”幸运,因为这些问题可能会在真正糟糕的事情发生之前被忽视。(我认识某个人用他的备份程序擦除了他的硬盘。(幸运的是,它也确实做了备份,只是删除了已经 -复制的东西。))
  • hmm..似乎是对的,我写了一个快速代码,指向 int 然后将 10 存储在其中。打印值。释放指针,打印与输出 0 相同的值。任何时间和任何次数,释放后它始终为 0。和你说的一样吗?
  • 更准确地说:当您访问不属于您的程序(不再)的内存时,例如释放的内存,无法预测会发生什么。只是简单的未定义行为。
  • 好的,我相信你,而且没有其他人回复
【解决方案2】:

画出(部分)结构的图,就像它在开始时的样子。可能需要几个来覆盖案例,比如有趣的节点是第一个/最后一个/唯一一个。现在仔细执行图表上代码中的每项操作,检查每一步后都没有出错。

在弄清楚如何进行操作时,同样的策略也有效:绘制之前/之后的图表,看看如何从头到尾。

【讨论】:

  • 这就是我在这里表达的意思,1->1->2 一旦ptr2在中间1,它应该连接(第一个1和最后2个)然后释放ptr2,现在将如何循环更新本身没有失败? (即这个 ptr2 = ptr2->next 将如何执行?
  • @codeymodey,所有涉及的变量需要更详细的分步图表。
猜你喜欢
  • 2020-10-30
  • 1970-01-01
  • 2015-01-20
  • 2013-01-08
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
相关资源
最近更新 更多