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

调用free()释放循环链表节点时为何会修改另一个指针的地址?

问题根因

你看到*temp_llnode_ptr的值发生异常变化,是访问已释放内存的未定义行为导致的,具体拆解逻辑:

  • 你写的temp_llnode_ptr = &(*list)->head->next; 并不是把head->next的值拷贝一份存下来,而是存了「第一个节点(地址0x7fffcf9c72f0)内部的next成员的内存地址」,也就是说*temp_llnode_ptr等价于直接读第一个节点的next字段。
  • 调用free_LL_node释放第一个节点的时候,会执行两个操作:
    1. 首先你主动把(*node)->next = NULL;,这时候已经修改了第一个节点的next值;
    2. 调用free(*node)释放第一个节点的内存,释放后的内存所有权归堆分配器,大部分堆实现会在释放的内存块里写入堆管理的元数据,用来维护空闲内存链表,这会直接覆盖这块内存里原来存储的所有内容,包括你原来的next字段。
  • 你后续打印*temp_llnode_ptr,本质是读已经被释放、已经被改写的内存,输出什么值都是合法的未定义行为,你看到的0x7fffcf9c6010就是堆管理器写入的元数据值。

额外的代码逻辑问题

你当前的释放逻辑还有两处明显错误:

  • 释放头节点后没有把链表的head指针指向第二个节点,而是直接设为NULL,后续遍历会直接崩溃
  • 循环链表释放需要注意不要出现循环访问,你当前按LL_length遍历的逻辑如果没有正确更新head,也会出现访问悬垂指针的问题

正确的释放逻辑可以参考:

void free_LL(LL_t** list) {
    if (!list || !*list) return;
    LL_node_t *current = (*list)->head;
    LL_node_t *next = NULL;
    for (int i = 0; i < (*list)->LL_length; i++) {
        next = current->next;
        free_LL_node(&current);
        current = next;
    }
    // 释放链表结构体本身
    free(*list);
    *list = NULL;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 18:54:02