链表节点必须用new分配内存,因为栈上局部变量函数返回后即销毁,返回其地址会导致悬空指针;而new在堆上分配,生命周期可控,配合delete或智能指针可安全管理。

为什么链表节点必须用 new 分配内存
栈上分配的局部变量在函数返回后自动销毁,如果用 Node node; 创建节点再取地址,返回的指针立刻悬空。链表需要长期存在的节点,必须用 new 在堆上申请内存——这是最常踩的坑,一写就崩溃。
正确做法是:每个节点都用 new Node 构造,且记得后续用 delete 释放(或改用 std::unique_ptr 自动管理)。
插入操作中 prev->next 和 new_node->next 的赋值顺序
在中间插入时,若先改 prev->next = new_node,再设 new_node->next = old_next,会导致 old_next 丢失(因为 prev->next 已指向新节点,无法再读到原来的下一个节点)。
安全顺序只有这一种:
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 先保存原链上的后继:
Node* old_next = prev->next; - 再连新节点的后继:
new_node->next = old_next; - 最后更新前驱的指针:
prev->next = new_node;
遍历时 while (curr != nullptr) 不能写成 while (curr)
虽然 while (curr) 在大多数编译器下等价,但语义模糊、可读性差,且一旦指针类型被包装(比如未来换成 std::shared_ptr<node></node>),while (curr) 可能不编译或行为异常。
明确写成 while (curr != nullptr) 是唯一稳妥写法。尤其在调试时,GDB 或日志里看到 nullptr 比看到一个“假值”更容易定位空指针问题。
删除节点时 double-delete 和野指针风险
删完节点后如果不把指针置为 nullptr,后续误用该指针会触发未定义行为;更危险的是,同一块内存被 delete 两次,程序大概率直接 abort。
标准做法是:
- 先备份要删的节点:
Node* to_delete = curr->next; - 跳过它:
curr->next = to_delete->next; - 再释放:
delete to_delete; - (可选但推荐)置空:
to_delete = nullptr;
真正难的是边界情况:删头节点时没有 prev,必须单独处理;空链表或单节点链表容易漏判 head == nullptr ——这些地方不加断点调试,很难靠肉眼发现。

















