栈中变量何时销毁?为何示例代码中局部变量内存可被正常访问?
局部变量销毁后仍可访问的原因解析
示例代码
#include <stdlib.h> #include <stdio.h> int* test() { int *p; if (1) { int y = 10; p = &y; } printf("Address = %p\n", p); printf("Value = %d\n", *p); return p; } int main() { int *ptr = test(); printf("Adress on main = %p\n", ptr); *ptr = 15; printf("Value on main = %d\n", *ptr); }
运行输出
Address = 0x7ffe7e84432c Value = 10 Adress on main = 0x7ffe7e84432c Value on main = 15
问题
我原本认为局部变量y会在if代码块或test函数结束时被销毁,访问其地址会触发Segmentation Fault(段错误),但实际运行一切正常,甚至能在main函数中通过指针修改该地址的值,想了解这一现象的原因:为何y的内存未被销毁?
解析
这不是内存没被“销毁”,而是局部变量离开作用域后,系统只是标记这块内存可以被后续代码复用,不会立刻清空或回收它:
- 局部变量
y存在于栈内存中,当if代码块执行完、test函数返回后,栈顶指针会向上移动,这块内存不再属于y,但里面原来的值不会马上被覆盖。 - 你的程序在访问这块内存时,刚好还没有其他代码占用它,所以能读到旧值甚至修改成功,但这属于未定义行为——换个编译器、加几行代码或者改变编译选项,结果可能完全不同,比如突然触发段错误、输出垃圾值,甚至程序崩溃。
- 段错误不是必然触发的,只有当程序访问了操作系统明确禁止的内存区域(比如已被回收的堆内存、内核空间)才会触发。栈上的“废弃”内存暂时还属于进程地址空间,所以操作系统不会立刻拦截访问,但这种行为绝对不安全,不能依赖。
内容的提问来源于stack exchange,提问作者Ermand
相关产品推荐
相关产品推荐

