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

为何调用free()后悬空指针仍能输出变量的地址与值?

问题解析与修正

核心错误:误用free释放栈内存

你代码里的关键问题是:free函数只能用来释放通过malloc/calloc/realloc从堆上分配的内存,但你调用free(a_ptr)时,a_ptr已经被赋值为栈变量a的地址&a,释放栈内存属于未定义行为——C标准没有规定这种操作会发生什么,程序可能正常运行、崩溃,或者出现随机异常结果。

为什么还能打印地址和值?

  • 指针变量a_ptr本身存储的是内存地址,free函数不会修改指针里的地址值,所以两次打印的地址都是&a,这是正常现象。
  • 栈变量a在main函数执行结束前一直存在于栈上,只要这块内存没有被后续操作覆盖,解引用指针依然能读到a的值。但这只是巧合,完全不能依赖,换个编译环境或修改代码后可能立刻出问题。

修正后的代码

场景1:需要先使用堆内存,再指向栈变量

记得先释放堆内存,再让指针指向栈变量,避免内存泄漏:

#include <stdio.h>
#include <stdlib.h>

int main() {

    int a = 1;

    // 分配堆内存并检查是否成功
    int *a_ptr = (int *)malloc(sizeof(int));
    if (a_ptr == NULL) {
        perror("malloc failed");
        return 1;
    }

    // 先释放堆内存,再指向栈变量
    free(a_ptr);
    a_ptr = &a;

    printf("The address of 'a' is %p\n", a_ptr);
    printf("The address of 'a' is %p\n", a_ptr);
    printf("The value of 'a' is %d", *a_ptr);

    return 0;
}

场景2:只需要指向栈变量

如果从一开始就想让指针指向栈变量a,那根本不需要malloc:

#include <stdio.h>

int main() {

    int a = 1;
    int *a_ptr = &a; // 直接指向栈变量

    printf("The address of 'a' is %p\n", a_ptr);
    printf("The address of 'a' is %p\n", a_ptr);
    printf("The value of 'a' is %d", *a_ptr);

    return 0;
}

重要提醒

未定义行为的危险性在于它的不可预测性——这次程序能正常运行不代表永远没问题,在不同编译器、操作系统或后续代码修改后,可能会出现崩溃、数据损坏等严重问题,一定要避免这种错误操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 23:22:16