You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++双向链表删除节点时二级指针与普通指针行为差异原因探究

根本原因

错误版本的核心问题是:你传入的二级指针deleteMe指向的是变量(要么是外部的head指针变量,要么是链表节点内部的next/prev指针成员)的存储地址,修改链表指针的操作会直接改变*deleteMe的取值,导致后续逻辑不再操作最初要删除的节点。

我们拿注释delete的第二次调用为例拆解执行过程,就能清晰看到差异:
初始状态(第一次调用执行完后):链表为3->2->1,head指向节点3,第二次调用为deleteNode(&head, &head->next)

  • 进入函数时,deleteMe指向的是节点3内部的next成员的存储地址,此时*deleteMe是节点2的地址,也就是你原本要删除的节点。
  • 执行(*deleteMe)->prev->next = (*deleteMe)->next时,就是把节点3的next赋值为节点1的地址。而deleteMe正好指向节点3的next,所以赋值完成后,*deleteMe直接变成了节点1的地址,你最初要删除的节点2已经找不到了。
  • 后续判断(*deleteMe)->next时,实际判断的是节点1的next,自然为空,你本该执行的「把节点1的prev修改为节点2的prev」逻辑直接跳过,节点1的prev仍然指向已经脱链的节点2。
  • 最终遍历链表时从head(节点3)出发,访问到的next已经是节点1,自然输出3->1,和正确版本结果不符。

如果没有注释delete:你最终delete *deleteMe的时候删除的是节点1而非原本要删的节点2,后续操作再访问head->next就是访问已经释放的野内存,直接触发崩溃。

而正确版本的deleteMe是传值参数,存的是你要删除的节点地址的副本,不管你怎么修改链表内部的指针,这个副本的值都不会变,全程操作的都是目标节点,逻辑完全正确。


内容的提问来源于stack exchange,提问作者IAmACoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:36:03