所以这是一个概念性的问题。我正在用C ++编写一个LinkedList,并且由于Java是我的第一语言,我开始编写我的removeAll函数,以便它只是将尾节点连接到头部(我使用的是Sentinel Nodes btw)。但我立即意识到这在C ++中不起作用,因为我必须为节点释放内存!
有没有办法绕过整个列表,手动删除每个元素?
答案 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)
是。好吧,有点......如果您实现列表以使用内存池,那么它负责该池中的所有数据,并且可以通过删除内存池(可能包含一个或多个大块内存)来删除整个列表)。
使用内存池时,通常至少需要考虑以下因素之一:
我不是这方面的专家。通常,当我需要快速内存管理时,它一直用于填充一次的内存,而不需要维护自由列表等。当您有特定的目标和设计约束时,内存池更容易设计和实现。如果你想要一些适用于所有情况的魔法子弹,你可能会运气不好。