如何"completely"删除链表中的所有节点?
How to "completely" delete all nodes in a linked list?
我对指针和删除指针在C++中的工作原理感到好奇,所以我设置了一个实验。我做了一个非常简单的单链表和以下递归函数,用于删除列表中的所有节点:
void deleteList(Node *node) {
if (!node)
return;
deleteList(node->next);
cout << "deleting node " << node->data << endl;
delete node;
node = nullptr;
}
我想这成功删除了列表中的所有节点。但是,在main中调用此函数后,我检查头节点是否仍然存在:
List list;
// appending a bunch of numbers to the list...
list.deleteList(list.head);
if (list.head)
cout << true;
这会将 1 打印到控制台,这意味着头部确实仍然存在。我希望头部和它之后的所有其他节点都是空的,因此 if 条件失败,因为将指针设置为 null 是我在递归函数中做的最后一件事。那么,为什么程序报告头部仍然存在呢?
编辑:更改列表列表(); 到列表列表;
您释放了内存,但分配给nullptr
仅影响传递给函数的指针副本,而不会影响调用方中的原始指针。
如果将函数声明为通过引用接收指针:
void deleteList(Node *&node) {
然后,node = nullptr;
的分配也会影响调用方。
请注意,由于您标记了此 C++11,因此通常将链表定义为正向的一系列 std::unique_ptr<Node>
s(如果它是双向的,则为反向的原始指针以避免引用周期),因此您可以避免需要特殊的删除器函数,只需将头部指针设置为 nullptr
并让C++做级联删除的工作。
编辑:让std::unique_ptr
做这项工作存在一个缺陷;正如评论中指出的那样,这意味着列表大小实际上受到堆栈的限制,当您删除它们时,太大的列表会导致堆栈溢出。因此,逐个显式清除(最简单的方法是正确实现弹出,并且清除只是弹出,直到head
通过popleft
方法转换为nullptr
)会更安全。我把原来的建议留给后人,所以这个解释是有道理的。
相关文章:
- 反向给定链表中的K节点
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- Boost Graph Library,修复节点大小
- C++A*算法并不总是在路径中具有目标节点
- 如何找到2个单链表的公共节点
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 为什么我的删除节点函数实际上没有删除节点?
- 我们可以删除链表中静态内存中的节点吗
- 如何在pugixml中获取节点的内部XML
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 节点 *temp; 和节点 *tmp = 新节点之间的差异
- 引擎节点:未定义的符号:_ZTV6Config
- 为什么"delete"关键字不删除节点?
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 如何按数字顺序插入链表节点?
- 为什么我的双向链表删除函数会删除多个节点?
- 如何"completely"删除链表中的所有节点?