C语言指针与自动存储期疑问:返回局部数组指针为何未输出空地址?
关于C语言局部变量生存期与指针的常见误解
首先明确:栈上的局部变量(比如你代码里的arr)在函数返回后,其占用的栈内存会被标记为可复用,但指向它的指针不会自动变成NULL。你看到的“正常运行”只是未定义行为下的巧合,不是正确的程序行为。
你的两段代码的本质问题
两段代码都是返回栈上局部数组的地址,属于C语言里的未定义行为:
- 函数
fun执行时,arr在栈上分配内存,arr(或arr2)保存的是这块栈内存的起始地址。 - 当
fun返回后,对应的栈帧被销毁,这块内存不再受程序控制,可能被后续函数调用覆盖,但指针p仍然保存着原来的地址值。 - 你用
printf("%p", p)输出的是指针本身存储的地址数值,不管这块内存是否有效,指针的数值不会自动改变——它不会变成NULL,只是指向的内存已经不可用了。
为什么malloc能解决问题
用malloc分配的内存来自堆空间,堆内存不会随函数返回自动释放,必须手动调用free才会释放。所以返回堆内存的指针是合法的,指针指向的内存始终有效(直到你主动释放)。
你可能混淆的点
你误以为“局部变量被释放后,指针会自动指向NULL”——这完全是错误的。C语言没有自动置空指针的机制,指针只是一个存储地址的变量,只要你没主动修改它的值,它就会一直保存原来的地址,哪怕这个地址对应的内存已经失效。
举个例子,如果你在printf之后再调用其他函数,比如:
p = fun(); printf("%p\n", p); // 调用其他函数,覆盖栈内存 printf("hello world\n"); // 再尝试访问p指向的内容,大概率会出错 printf("%d\n", *p);
这时你会发现*p的结果完全不可预料,甚至程序崩溃,这就是未定义行为的表现。
内容的提问来源于stack exchange,提问作者Heitor E. Rezende
相关产品推荐
相关产品推荐

