C语言指针与局部变量:为何这段代码能正常运行?
为什么指向已销毁局部变量的指针还能正常取值?
先看你给出的代码:
void changeValue(int **ptr) { int y = 19; *ptr = &y; } int main() { int x = 14; int *ptr = &x; printf("%d\n", *ptr); changeValue(&ptr); printf("%d\n", *ptr); return 0; }
你观察到输出是14、19,但疑惑局部变量y销毁后指针应该指向无效内存,这其实是未定义行为的巧合表现,不是真的“正常运行”,原因如下:
- 局部变量
y存在栈内存中,函数changeValue执行完毕后,栈帧会被标记为可复用,但内存里的旧值不会被立刻清零或覆盖。此时你访问*ptr,刚好那块内存还没被后续操作改写,所以能读出之前的19,但这完全是随机的运气。 - 栈的空间是重复利用的:如果在第二个
printf之后加一些函数调用(比如再调用一次printf或者其他函数),再去访问*ptr,大概率会得到垃圾值,甚至触发程序崩溃——因为此时原来y的栈空间已经被新的栈帧覆盖了。 - 从C语言标准的角度来说,访问生命周期结束的局部变量的内存属于未定义行为,编译器可以做任何处理:可能像你现在这样读出旧值,可能直接崩溃,可能输出完全无关的数值,甚至开启优化后这段代码会被编译器直接修改逻辑。
内容的提问来源于stack exchange,提问作者Lukic
相关产品推荐
相关产品推荐

