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

函数内局部char数组指针返回后printf打印异常的原因探究

问题现象说明

情况1:返回局部字符数组指针,printf("%s")无输出

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%s",cp);
}

char* getcc(){
  char c_arr[] = "cow";
  return c_arr;
}

运行后无任何输出。

情况2:将数组改为全局变量,printf("%s")正常输出

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%s",cp);
}
char c_arr[] = "cow";
char* getcc(){
  return c_arr;
}

输出:

cow

情况3:使用printf("%c")逐个打印字符,可输出内容

#include<stdio.h>
char* getcc();

int main(){
  char *cp = getcc();
  printf("%c%c%c",*cp,*++cp,*++cp);
}

char* getcc(){
  char c_arr[] = "cow";
  return c_arr;
}

输出:

cow

原因分析
  • 局部数组的内存特性:getcc()里的c_arr是局部变量,存储在栈内存中。当函数执行完毕返回时,该函数对应的栈帧会被销毁,栈上的内存会被标记为可复用状态。此时返回的指针指向的是已经失效的内存区域,属于野指针,用printf("%s")访问时,%s会从指针位置开始读取直到遇到\0,但此时栈内存的数据已经不可靠,可能已经被覆盖,所以无法正常输出字符串。

  • 全局数组的内存特性:全局变量存储在静态存储区,这块内存从程序启动到结束都会持续存在,不会随函数调用结束而释放。所以getcc()返回的指针始终指向有效的内存区域,printf("%s")可以正常读取到完整的字符串。

  • %c逐个打印能输出是巧合:这是未定义行为的一种表现。函数返回后,栈帧虽然被销毁,但如果后续没有其他操作覆盖这块栈内存,原来的字符数据可能暂时还保留着。此时用%c直接读取指针指向的几个字节,刚好能读到原来的字符。但这种行为完全不可靠——只要调整编译器优化等级、在getcc()返回后增加其他函数调用,或者更换运行环境,就可能输出乱码或者程序崩溃,本质还是非法访问了已失效的内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:12:44