【问题标题】:Why does destructor run into unallocated memory?为什么析构函数会遇到未分配的内存?
【发布时间】:2020-07-18 00:02:26
【问题描述】:

我有一个单链循环链表,并且正在编写一个析构函数来删除所有节点。析构函数首先将头部与其余部分分离以防止无限循环,然后循环遍历列表并删除所有节点,最终,循环返回头部并将其删除。在程序中,我检查以确保指向节点的指针不为 NULL,我运行了调试器,它显示它在应该结束循环的点为 NULL,但循环继续并运行到未分配的内存中.这是我的代码:

    node<T> *cur = head;
    node<T> *nxt = head->next;
    if (nxt) cur->next = nullptr;
    cur = nxt;

    // walk through the list and delete nodes
    while (cur) {
        cur = cur->next;
        delete cur;
    }

编辑:将代码更改为

  node<T> *cur = head;
    node<T> *nxt = head->next;
    if (nxt) cur->next = nullptr;
    cur = nxt;

    // walk through the list and delete nodes
    while (cur) {
        nxt = cur->next;
        delete cur;
        cur = nxt;
    }

编辑 2: 再次更改代码以处理边缘情况,同样的问题仍然存在。

if (head ==  NULL) return;
    else if (head->next == head) delete head;
    else {
        node<T> *cur = head;
        node<T> *nxt = head->next;
        cur->next = nullptr;
        cur = nxt;
        while(cur) {
            nxt = cur -> next;
            delete cur;
            cur = nxt;
        }
    }

【问题讨论】:

  • 更仔细地遵循您的循环逻辑。 delete cur; -- 那么在那一行之后cur 会发生什么?你已经摧毁了它。那么while(cur) 会发生什么?
  • 啊,可能需要一个临时指针
  • 问题与我的删除功能有关,该功能正在删除列表的头部。

标签: c++ linked-list destructor dynamic-memory-allocation


【解决方案1】:

这与切断无关,您在删除元素时遍历列表的代码在非循环列表中同样错误。你推进指针然后删除它指向的(下一项)。

您需要删除 current 项目(当然,您还需要在该点之前提取其 next 字段,因为一旦删除,所有内容都将变为未定义),例如:

while (cur != nullptr) {
    node<T> *toDelete = cur;
    cur = cur->next;
    delete toDelete;
}

就您需要的完整解决方案而言,算法应该是:

def delCircList(head):
    # Ignore empty list.

    if head == null:
        return

    # Special for one-element list.

    if head.next == head:
        free head
        return

    # Sever link and set start point.

    curr = head.next
    head.next = null

    # Use normal deletion algorithm.

    while curr != null:
        toDelete = curr
        curr = curr.next
        free toDelete

【讨论】:

  • 是的,改了还是不退出循环
  • @Ender_The_Xenocide:您应该知道,在切断之前,if (nxt)永远为假(因为它是一个循环列表)。建议您将我添加的伪代码视为有用的基线。
  • 这类似于我的实现,失败的是循环检查,正如我所说我运行调试器并且当检查发生但不退出循环时 cur 的值为 null
  • @Ender_The_Xenocide:见我上面的第一条评论。因为nxt 在循环(非切断)列表中永远不会为空,所以您不能使用它来切断列表。因此,您有一个无限循环,因为它仍然是圆形的。你最好使用我发布的伪代码来处理空(head == null)和单元素(head.next == head)列表作为特殊情况,然后在这些情况不正确的情况下进行迭代工作。
  • 如果它永远不会是假的,那么列表应该总是被切断吗?反之亦然。
猜你喜欢
  • 2013-12-22
  • 2018-08-24
  • 2014-04-19
  • 2021-07-17
  • 2017-05-25
  • 2021-12-31
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多