单链表节点删除中临时变量tmp的作用及代码替换疑问
对free(tmp)函数的困惑
核心问题拆解
首先明确:tmp=q->link; q->link=tmp->link; 和 q->link=q->link->link; 这两段代码,在修改链表结构的逻辑上是完全等价的——都是让当前节点q跳过它的下一个节点,直接指向原下下个节点,从而把中间的节点从链表中"摘除"。
你替换后调用display()仍看到原链表,大概率是测试场景的问题,而非代码逻辑本身:
- 可能你要删除的节点没被匹配到(比如输入的
data和链表节点的info不匹配,或者循环条件while(q->link->link!=NULL)只处理非尾节点,你测试的是尾节点却替换了中间节点的代码块); - 也可能
display()函数的实现有问题(比如没有正确判断link为NULL就停止遍历,或者误访问了已释放但未被覆盖的内存)。
tmp变量的作用
tmp的核心作用就是暂存被删除节点的内存地址:
当你执行q->link=q->link->link;后,原q->link(也就是被删除节点的地址)就被覆盖了,你再也找不到这块内存的位置,自然无法调用free()释放它。而用tmp先把这个地址存起来,就能在修改链表指针后,安全释放掉被摘除节点的内存,避免内存泄漏——虽然不释放内存程序也能运行,但长期运行会占用越来越多的系统内存。
指针q和start的特性
- start是全局指针:它指向链表的头节点,全局变量的作用域覆盖整个程序,所有函数都能直接访问和修改它指向的内容。
- q是局部指针:它是
del函数内的局部变量,你把start的值赋给q,只是让q和start指向同一个内存地址(链表的头节点)。q并没有创建链表的副本,它操作的就是原链表的堆内存——修改q->link本质是直接修改堆上节点的link成员,这种修改会直接反映到原链表上,因为start指向的就是这块堆内存。
补充说明
你替换代码后如果只是去掉了tmp相关代码但保留free(),那肯定会报错;如果连free()也去掉了,链表结构其实已经修改,只是被摘除的节点还留在内存里,若display()遍历逻辑有问题,可能会误访问到这块未被释放的内存,看起来像是没删除。
内容的提问来源于stack exchange,提问作者Midhun Raj
相关产品推荐
相关产品推荐

