此问题已在此处有答案:
How to access a local variable from a different function using pointers?(10个答案)
25天前关闭
我是一个初学C的人,我试着写一个函数,它应该返回一个字符串,但当我试图打印从函数获得的结果时,我只得到(null)
下面是我的代码:
char *reverse(char *str) {
char result[20];
/* logic */
return result;
}
int main() {
char str[20];
printf("Enter a string: ");
scanf("%[^\n]s", str);
printf("The string reversed is: %s", reverse(str));
}
为什么这个打印(null)
,当我注意到这样的东西工作得很好:
char *func() {
return "hello";
}
int main() {
printf("%s", func());
}
2条答案
按热度按时间hjqgdpho1#
函数
reverse()
返回一个指针,指向在函数体中使用局部作用域定义的数组:当函数返回并且指针变为无效(悬空指针)时,此数组将超出作用域。从无效指针进行阅读具有未定义的行为。令人惊讶的是,printf
为此输出(null)
,但未定义的行为意味着任何事情都可能发生,不要感到惊讶,不要期望下一次发生同样的行为,试图解释实际观察到的行为是徒劳的。你应该使数组
static
或从堆中分配它,或者更好地,把目标数组作为参数。注意
scanf("%[^\n]s", str)
是不正确的:s
没有意义,应该删除;str
中的最大字符数,以避免潜在的缓冲区溢出:scanf("%19[^\n]", str)
scanf()
的返回值来检测无效或丢失的输入,比如一个空行。以下是修改后的版本:
k5ifujac2#
您的代码段打印(null)的原因是您从reverse函数返回了一个本地数组结果,这是一个堆栈分配的数组。一旦reverse函数返回,结果数组的内存将被释放,并留下一个悬空指针。如果忽略此指针,则会导致未定义的行为,在您的情况下,它恰好是print(null)。
1.我们使用malloc为结果字符串动态分配内存。字符串的长度由strlen(str)决定,我们加1来容纳空终止符。
1.我们将输入字符串str中的字符以相反的顺序复制到动态分配的结果字符串中。
1.我们确保结果字符串以空终止。
1.在使用反转字符串之后,使用free释放动态分配的内存以避免内存泄漏是很重要的。