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

链表节点内存释放后,为何仍能访问到val值?

链表内存释放后的指针访问疑问

假设有链表:[1] -> [2] -> [3] -> [4],节点结构体定义如下:

typedef struct Node
{
    int val;
    struct Node* next;
}Node;

持有链表的head指针,执行以下内存释放操作:

printf("%i", head->val); // 输出1

Node* tmp = head;
while(tmp != NULL)
{
    Node* tmp2 = tmp;
    tmp = tmp->next;
    free(tmp2);
}

printf("%i", head->val); // 输出一个大数,但不为NULL

if (tmp == NULL)
{
    print("is null"); // 此语句会执行
}

疑问

为何head->val仍可访问且不为NULL,而tmp为NULL?释放内存后head->val不该变为NULL吗?既然head是指针,指向的地址已被free,为何还能访问到值?


解答

  • free()的本质是把内存归还给操作系统,它不会修改指针本身的值,也不会主动清空内存里的原有数据。head指针依然保存着原来的内存地址,只是这块地址现在已经不属于你的程序了。
  • 访问已被free的内存属于未定义行为:操作系统可能暂时还没覆盖这块内存的内容,你就可能读到旧值;也可能已经把这块内存分配给其他程序/数据,你读到的就是垃圾值(比如代码里的那个大数)。运气差的话,甚至会直接触发程序崩溃——这些情况都没有固定规律,完全取决于系统的内存管理机制。
  • tmp最终是NULL和free无关:循环里每次都会先把tmp更新为tmp->next,再释放当前节点。当遍历到最后一个节点(值为4的节点)时,tmp会被更新为它的next(也就是NULL),然后释放最后一个节点,循环结束后tmp自然就是NULL。
  • 别混淆类型:head->val是int类型,而NULL是指针类型的空值标记,两者完全不是一个类型,int变量不可能变成NULL。你可能把“指针本身被置空”和“指针指向的内容”搞混了——free既不会把head置为NULL,也不会修改它指向的val的值(只是这块内存不再属于你了)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 06:39:15