【问题标题】:Delete linked list删除链表
【发布时间】:2011-05-06 00:03:43
【问题描述】:

嘿,我想知道 我编写了一个 C++ 链表,我在其中调用析构函数来遍历分配的链表并删除找到的每个节点。然而我发现,虽然它通过链表并删除每一次出现它仍然会打印出值。虽然只是一些废品价值。

但是当我删除linked_list 时,它不应该是下次不能打印吗? 我在删除列表时使用newdelete 创建链接列表

sorted_list::~sorted_list()
{
    // Destructor implementation
    destroy(this->first);
    cout << "Destructor called sorted_list" << endl;
}

void sorted_list::destroy(list_link* item)
{
  if (item)
  {
    destroy(item->next);
    delete item;
  }
}

打印功能

void sorted_list::print() {

    if(this->first)
    {
        iteratorn *traverse = new iteratorn(this->first);
        while( !traverse->iterator_end() )
        {
            cout << traverse->iterator_get_key() << " ";
            traverse->iterator_next();
        }
        delete traverse;
    }
    else
        cout << "list empty" << endl;
}

【问题讨论】:

  • 没有足够的代码。显示构建列表的代码,并显示打印出不应该输出的值的代码。
  • 你删除这个->前两次(一次在销毁中)。
  • 你不需要在析构函数中将NULL(甚至0)分配给this-&gt;first。列表发布了,它消失了,完全无法访问。
  • @Roger Pate @wilhelmtell 感谢您的输入我删除了这个的双重删除->现在首先

标签: c++ linked-list


【解决方案1】:

缺少的部分无效。删除后,您必须至少取消第一个节点。删除后我会取消每个节点。

【讨论】:

    【解决方案2】:

    在声明链接时,可能看起来或多或少是这样的:

    struct list_link {
        int data;
        list_link *next;
    };
    

    你可以插入一个析构函数

    struct list_link {
        int data;
        list_link *next;
        ~list_link() { delete next; }  // MAKE SURE NULL-TERMINATED LIST
    };
    

    这样,如果你想删除列表,你可以简单地:

    delete first;
    

    魔法!!

    【讨论】:

      【解决方案3】:

      当你访问一个被破坏的对象时,行为是未定义的。事实上,删除一个对象并不会清除内存,只是将其标记为可用,所以如果你对已经删除的对象执行一些操作,它们可能会做一些合理的事情。但同样,该对象已被破坏,因此您不能访问它。

      当然,在链表被销毁后,你不应该保留任何指向链表对象的指针,因为这些对象也会被销毁。

      顺便说一句,你的sorted_list::destroy 是递归的,效率很低。您可能需要用迭代方法替换它:

      void sorted_list::destroy(list_link* item)
      {
          while (item)
          {
              list_link* old = item;
              item = item->next;
              delete old;
          }
      }
      

      (并且您应该考虑@Roger Pate 的评论,不要在第二次调用destroy(this-&gt;first); 后删除this-&gt;first。)

      【讨论】:

      • 是的,总是迭代地销毁列表,因为如果列表太大,递归方法可能会耗尽堆栈空间。
      • @Vlad @Timo 这不准确。任何现代 C++ 编译器都应该知道如何优化掉至少尾递归。在这里,将递归转换为尾递归实际上很简单,结果目标代码应该与循环相同:if( ! item ) return; list_link* next = item-&gt;next; delete item; destroy(next);
      • @wilhelmtell:假设优化器会为您优化递归是一种危险的做法。除非 C++ 标准保证这样的优化,否则我不会依赖它。
      • 我一直在尝试,但仍然不明白为什么我仍然保留废品价值。当我尝试访问已删除的链表时,我实际上希望程序崩溃,但它会打印出一些废值。我也添加了打印功能。
      • @starcom:你不能保证崩溃,行为是未定义的。看,当你破坏对象时,内存被释放,并返回到全局内存池。所以它可能随时被任何值覆盖,或者它可能仍然具有它的旧值,你永远不知道。如果它碰巧有旧值,您的打印功能可能不会崩溃。而且你不能保证函数会崩溃,因为这需要用一些特殊的值来填充内存——但这是不可能的,因为内存可以被其他对象重用。看到了吗?
      猜你喜欢
      • 2013-11-22
      • 2017-05-19
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      相关资源
      最近更新 更多