VS Code中GCC编译下char指针传递输出异常问题求助
问题分析与解决
代码与现象
#include<stdio.h> #include<stdlib.h> #include<string.h> int funct(int *value,char **text){ char a[]="hello World"; *text=a; *value=2; return(0); } int main(){ int a=1; char *ptr; funct(&a,&ptr); printf("%d %s",a,ptr); getchar(); return(0); }
实际输出:2 hell
预期输出:2 hello World
问题表现:int类型数值能正常从函数传递到main函数,但char*指向的字符串输出异常。调试时发现执行printf前ptr看似指向正确内容,但实际输出却被截断。
核心原因
函数funct中的char a[]="hello World"是局部栈数组,它的内存分配在函数的栈帧上。当funct执行完毕返回后,该栈帧会被销毁,对应的内存空间会被后续函数调用(比如printf、getchar)的栈数据覆盖。
*text=a;只是把局部数组的地址赋值给了main里的ptr,当funct返回后,ptr就变成了野指针——指向已经被释放的内存区域,此时访问ptr属于未定义行为。调试时如果在funct刚返回还没调用printf时查看ptr,栈内存可能还没被改写,所以看起来正常,但执行printf时,printf的栈帧会覆盖原funct的栈空间,导致ptr指向的内容被破坏,出现截断或乱码。
解决办法
方案1:使用全局数组
将数组定义在函数外部,存储在全局数据区,函数返回后不会被释放:
#include<stdio.h> #include<stdlib.h> #include<string.h> char a[]="hello World"; // 全局数组 int funct(int *value,char **text){ *text=a; *value=2; return(0); } int main(){ int a=1; char *ptr; funct(&a,&ptr); printf("%d %s",a,ptr); getchar(); return(0); }
方案2:动态分配堆内存
用malloc在堆上分配内存,堆内存不会随函数返回而释放,注意使用后要free避免内存泄漏:
#include<stdio.h> #include<stdlib.h> #include<string.h> int funct(int *value,char **text){ const char *msg = "hello World"; *text = malloc(strlen(msg) + 1); // +1 存储字符串结束符'\0' if (*text == NULL) { *value = -1; // 标记分配失败 return -1; } strcpy(*text, msg); *value=2; return(0); } int main(){ int a=1; char *ptr = NULL; funct(&a,&ptr); if (ptr != NULL) { printf("%d %s",a,ptr); free(ptr); // 释放堆内存 } getchar(); return(0); }
方案3:由调用者提供缓冲区
让main函数传入缓冲区,避免在子函数中使用局部栈数组:
#include<stdio.h> #include<stdlib.h> #include<string.h> int funct(int *value,char **text, char *buf, size_t buf_size){ const char *msg = "hello World"; if (buf_size < strlen(msg) + 1) { *value = -1; // 缓冲区不足 return -1; } strcpy(buf, msg); *text = buf; *value=2; return(0); } int main(){ int a=1; char *ptr; char buf[20]; // 调用者提供缓冲区 funct(&a,&ptr, buf, sizeof(buf)); printf("%d %s",a,ptr); getchar(); return(0); }
内容的提问来源于stack exchange,提问作者synapsis
相关产品推荐
相关产品推荐

