C ++链接列表删除所有

时间:2012-08-23 01:53:51

标签: c++ memory-management data-structures linked-list removeall

所以这是一个概念性的问题。我正在用C ++编写一个LinkedList,并且由于Java是我的第一语言,我开始编写我的removeAll函数,以便它只是将尾节点连接到头部(我使用的是Sentinel Nodes btw)。但我立即意识到这在C ++中不起作用,因为我必须为节点释放内存!

有没有办法绕过整个列表,手动删除每个元素?

3 个答案:

答案 0 :(得分:7)

你可以使每个节点拥有下一个节点,即负责在它自身被销毁时销毁它。您可以使用std::unique_ptr

之类的智能指针来完成此操作
struct node {
    // blah blah
    std::unique_ptr<node> next;
};

然后你可以破坏第一个节点,所有其他节点都将被解释:它们将在unique_ptr析构函数的连锁反应中被破坏。

如果这是双向链接列表,则不应在两个方向上使用unique_ptr。这将使每个节点拥有下一个节点,并由下一个节点拥有!您应该使此所有权关系仅在一个方向上存在。在另一个使用常规非拥有指针:node* previous;

但是,这不会像Sentinel节点那样工作:它不应该被销毁。如何处理这取决于如何识别标记节点和列表的其他属性。

如果您可以轻松地分辨出哨兵节点,例如检查布尔成员,则可以使用自定义删除器来避免删除哨兵:

struct delete_if_not_sentinel {
    void operator()(node* ptr) const {
        if(!ptr->is_sentinel) delete ptr;
    }
};

typedef std::unique_ptr<node, delete_if_not_sentinel> node_handle;

struct node {
    // blah blah
    node_handle next;
};

这可以阻止哨兵的连锁反应。

答案 1 :(得分:1)

如果你使用了c ++ garbage collector,你可以像Java一样。没有多少。在任何情况下,它都会为您节省最多的运行时间因素,因为您花费了成本来分配列表中的每个元素。

答案 2 :(得分:0)

是。好吧,有点......如果您实现列表以使用内存池,那么它负责该池中的所有数据,并且可以通过删除内存池(可能包含一个或多个大块内存)来删除整个列表)。

使用内存池时,通常至少需要考虑以下因素之一:

  • 对象的创建和销毁方式的限制;
  • 您可以存储哪种数据的限制;
  • 每个节点上的额外内存要求(以引用池);
  • 一个简单,直观的游泳池,而不是一个复杂,混乱的游泳池。

我不是这方面的专家。通常,当我需要快速内存管理时,它一直用于填充一次的内存,而不需要维护自由列表等。当您有特定的目标和设计约束时,内存池更容易设计和实现。如果你想要一些适用于所有情况的魔法子弹,你可能会运气不好。