为何调用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
相关产品推荐
相关产品推荐

