返回局部auto变量指针:为何两种写法一种崩溃一种输出7?
为什么返回指向局部auto变量的指针时两种写法表现不同?
首先必须明确:这两段代码都是错误的,属于C语言中的未定义行为。返回指向局部auto变量的指针本身就违反了C语言的内存规则——局部auto变量存在于函数的栈帧中,函数执行完毕后,栈帧会被销毁,对应的内存空间会被标记为可复用,不再受程序合法管控,后续访问这块内存的结果完全不可预测。
为什么两段代码表现不同?
- 第一段代码直接返回
&i后触发段错误,是因为你的运行环境在函数栈帧销毁后,直接将这块内存标记为不可访问(比如某些系统会用特定值填充已释放的栈内存,或者设置内存保护),当main中尝试解引用指针时,就触发了内存访问错误。 - 第二段代码能输出7,纯粹是巧合:函数
func执行完毕后,栈帧虽然被销毁,但内存里的旧值不会被立即清零或覆盖。在main中调用printf时,栈帧的操作可能还没覆盖到原来i所在的内存位置,所以旧值7仍然保留,被printf读了出来。但只要你在func返回后增加其他函数调用或变量操作,这块内存就会被覆盖,届时再解引用指针就会输出垃圾值甚至触发段错误。
两段错误代码示例
第一段代码:
#include<stdio.h> int *func() { int i = 7; return &i; } int main(void) { int *a; a = func(); printf("%d", *(a)); return 1; }
第二段代码:
#include<stdio.h> int *func() { int i = 7; int *ip = &i; return ip; } int main(void) { int *a; a = func(); printf("%d", *(a)); return 1; }
总结
无论哪种写法,返回局部auto变量的指针都是错误的,不要因为某次运行结果符合预期就认为代码正确。正确的做法是使用静态存储期变量(static修饰)、动态分配内存(malloc/calloc),或者让调用者提供内存缓冲区,来避免这类问题。
内容的提问来源于stack exchange,提问作者A_normal_guy
相关产品推荐
相关产品推荐

