作为 this question 的后续行动:
据我所见,这应该可以按预期工作:
void greet(){
char c[] = "Hello";
greetWith(c);
return;
}
但这会导致未定义的行为:
char *greet(){
char c[] = "Hello";
return c;
}
如果我是对的,修复第二个问候功能的最佳方法是什么?在嵌入式环境中?在桌面上?
最佳答案
你完全正确。第二个示例中的 c 数组正在堆栈上分配,因此内存将立即被重用。特别是,如果你有类似的代码
printf("%s\n",greet());
你会得到奇怪的结果,因为对 printf 的调用会重用你数组的一些空间。
解决方案是将内存分配到其他地方。例如:
char c[] = "Hello";
char * greet() {
return c;
}
会工作的。另一种选择是在范围内静态分配它:
char * greet() {
static char c[] = "Hello";
return c;
}
因为静态内存是在数据空间中与堆栈分开分配的。
您的第三个选择是通过 malloc 在堆上分配它:
char * greet() {
char * c = (char *) malloc(strlen("Hello")+1); /* +1 for the null */
strcpy(c, "Hello");
return c;
}
但是现在你必须确保内存以某种方式被释放,否则你有内存泄漏。
更新
其中一个似乎比我预期更令人困惑的事情是“内存泄漏”到底是什么。泄漏是指您动态分配内存,但丢失了地址,因此无法释放。这些示例都不一定存在泄漏,但只有第三个示例甚至可能存在泄漏,因为它是唯一动态分配内存的示例。因此,假设第三种实现,您可以编写以下代码:
{
/* stuff happens */
printf("%s\n", greet());
}
这有泄漏;返回指向 malloc 内存的指针,printf
使用它,然后它就丢失了;你不能再释放它了。另一方面,
{
char * cp ;
/* stuff happens */
cp = greet();
printf("%s\n", cp);
free(cp);
}
不会 泄漏,因为指针保存在自动变量 cp
中的时间足够长,可以在其上调用 free()
。现在,即使 cp 在执行结束后立即消失,他结束大括号,由于已调用 free,内存被回收并且没有泄漏。
关于c++ - 由于我无法返回局部变量,从 C 或 C++ 函数返回字符串的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/423186/