C语言中返回字符串的函数调用后输出(null)的原因咨询
C语言中返回字符串的函数调用后输出(null)的原因咨询
嗨,我来帮你把这个问题的核心点讲清楚~
先看你写的reverse函数:
char *reverse(char *str) { char result[20]; /* logic */ return result; }
这里的result是局部数组,它是分配在函数的栈帧上的。当函数执行完毕返回时,这个栈帧会被系统销毁,对应的内存空间会被回收或者后续被其他函数调用覆盖。你返回的是这个局部数组的地址,但此时这个地址已经完全失效了——就像你把一个已经被拆掉的房子的地址给了别人,对方去找的时候自然啥也找不到,所以printf才会输出(null)(不同环境下可能会显示乱码,但你遇到的是null的情况)。
再看你提到的能正常工作的例子:
char *func() { return "hello"; }
这里返回的"hello"是字符串字面量,它在程序编译阶段就被存放在程序的只读数据段里,这个内存区域的生命周期和整个程序的运行周期一致,所以哪怕函数执行完返回了,这个地址依然有效,printf能正确找到对应的字符串内容。
那怎么解决你的reverse函数问题呢?给你几个实用的方案:
方案一:让调用方提供目标数组
不在函数内部创建局部数组,而是让调用方传入一个数组用来存放反转后的结果,这样就不会有内存失效的问题:void reverse(char *str, char *result) { int len = strlen(str); for(int i=0; i<len; i++){ result[len-1-i] = str[i]; } result[len] = '\0'; // 别忘了加字符串结束符 } int main() { char str[20]; char result[20]; printf("Enter a string: "); scanf("%[^\n]s", str); reverse(str, result); printf("The string reversed is: %s", result); }方案二:动态分配堆内存
在函数里用malloc在堆上分配内存,堆内存不会随函数返回而销毁,但要记得在调用方用完后用free释放,避免内存泄漏:char *reverse(char *str) { int len = strlen(str); char *result = malloc(len + 1); // 要给字符串结束符留位置 if(result == NULL){ perror("malloc failed"); return NULL; } for(int i=0; i<len; i++){ result[len-1-i] = str[i]; } result[len] = '\0'; return result; } int main() { char str[20]; printf("Enter a string: "); scanf("%[^\n]s", str); char *reversed = reverse(str); if(reversed != NULL){ printf("The string reversed is: %s", reversed); free(reversed); // 用完一定要释放堆内存 } }方案三:使用静态数组(不推荐)
把局部数组改成静态数组,它会被存放在全局数据段,生命周期和程序一致,但这种方式有弊端——静态数组是全局共享的,多线程环境下会有冲突,而且每次调用函数都会覆盖之前的结果:char *reverse(char *str) { static char result[20]; // 静态数组存放在全局数据段 int len = strlen(str); for(int i=0; i<len; i++){ result[len-1-i] = str[i]; } result[len] = '\0'; return result; }
备注:内容来源于stack exchange,提问作者Stillswarm
相关产品推荐
相关产品推荐

