You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言局部变量返回与动态内存分配代码运行异常问题咨询

问题根本原因

第一段代码运行异常的核心是函数返回了栈区局部变量的内存地址,触发了C语言的未定义行为。

底层原理讲解

C语言程序运行时的内存空间通常分为多个逻辑区域,和该问题直接相关的是栈区与堆区:

  • 栈区由操作系统自动管理:函数调用时会在栈区为当前函数开辟专属的栈帧,函数内的非静态局部变量、参数都存储在栈帧中;当函数执行结束返回时,对应的栈帧会被系统自动回收,这片内存的使用权会被释放,后续的函数调用会直接复用这块空闲的栈空间。
  • 堆区由程序员手动管理:调用malloc类函数申请的内存位于堆区,只要不主动调用free释放,这片内存的使用权会一直有效,直到程序退出。

对应第一段代码的执行逻辑:

  1. 第一次调用foo(0)时,栈上为foo开辟栈帧,局部数组arr的3个int空间就在这个栈帧里,存入[0,1,2]后返回arr的地址给a1。但foo执行结束后栈帧被回收,a1就成了指向无效内存的野指针。
  2. 第二次调用foo(3)时,系统会直接复用第一次foo调用释放的栈空间来创建新栈帧,所以原来a1指向的内存会被覆盖为[3,4,5],调用结束后这个栈帧也被回收,a2同样变成野指针。
  3. 后续执行printf时,printf自身的执行也需要占用栈空间,会再次复用这片刚释放的栈内存,把a2指向的内存数据冲成乱码,而a1指向的内容刚好还没被完全覆盖,就出现了你看到的输出结果。这类未定义行为没有任何确定性,换编译环境、运行参数都可能出现完全不同的结果,甚至程序直接崩溃。
修改后代码正常的原因

修改后用malloc申请的数组内存位于堆区,不会随foo函数执行结束被系统自动回收,返回的指针指向的内存是合法有效的,所以可以正常输出预期结果。注意使用完后需要手动调用free(a1)、free(a2)释放堆内存,避免出现内存泄漏问题。

内容的提问来源于stack exchange,提问作者Hayato Koyama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:39:04