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

为何free()会影响list->next指针?链表内存疑问求助

链表内存管理问题解答

问题描述

在实现链表添加节点时遇到以下问题:将list->next指向指针n的地址后,调用free(n),再次打印第二个节点的int值时变为垃圾值。想搞清楚:

  • 内存中n和list->next是持有相同地址的独立指针还是同一指针?
  • 若为独立指针,为何free(n)会影响list->next?
  • free(n)后第二个节点已失效,为何仍能通过list->next->next添加第三个节点?

代码示例

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

typedef struct node {
    int number;
    struct node *next;
} node;

int main(void) {
    node a;
    a.number = 1;
    a.next = NULL;
    node *list = NULL;
    list = &a;           // 第一个节点
    printf("%i\n", a.number);

    node *n = malloc(sizeof(node)); // 创建指向第二个节点的指针
    if (n != NULL) {
        n->number = 2;
        n->next = NULL;
    }

    list->next = n; // 将节点加入链表

    printf("%p\n%p\n", n, list->next);   // 打印地址
    printf("%i\n", list->next->number);

    free(n);

    printf("%p\n%p\n", n, list->next);   // 再次打印地址
    printf("%i\n", list->next->number);

    n = malloc(sizeof(node));

    printf("%p\n%p\n", n, list->next);
    if (n != NULL) {
        n->number = 3;
        n->next = NULL;
    }
    list->next->next = n;
    printf("%i\n", (*(*(*list).next).next).number);
    return 0;
}

输出结果

1 
0x5562319d62a0 
0x5562319d62a0 
2 
0x5562319d62a0 
0x5562319d62a0 
1445140950 
0x5562319d62a0 
0x5562319d62a0 
3

问题解答

  • n和list->next是独立指针:它们是两个完全独立的指针变量——n是main函数的局部变量,list->next是结构体a的成员变量,各自占用不同的内存空间。只是它们存储的数值相同,都是指向同一块堆内存的地址,所以输出里两者的地址值完全一致。

  • free(n)影响的是指针指向的内存,而非指针本身:free()函数的作用是释放指针指向的堆内存,不是销毁指针变量。当你调用free(n)后,n和list->next共同指向的那块内存被操作系统回收,标记为可复用区域,里面原来存储的2不再受保护,后续可能被其他数据覆盖,所以读取list->next->number会得到垃圾值。此时list->next这个指针变量本身的数值(地址)并没有改变,只是它指向的内存已经失效。

  • 通过list->next->next添加节点属于未定义行为:free(n)后,list->next变成了野指针(指向已释放的内存),对野指针进行解引用(比如访问list->next->next)是C语言标准明确的未定义行为。这次运行看似成功,只是因为那块被释放的内存暂时还没被操作系统分配给其他操作,没有被覆盖,但这种行为完全不可靠,随时可能导致程序崩溃、数据损坏等问题,绝对不能在实际代码中这么写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:15:36