c++ - 由于我无法返回局部变量,从 C 或 C++ 函数返回字符串的最佳方法是什么?

标签 c++ c memory

作为 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/

相关文章:

python - numpy.load 给出 ValueError : descr is not a valid dtype descriptor:

c - typedef char (*fptr1())(); 的用法

c - 在相同偏移量的两个整数中快速搜索一些半字节(C,微优化)

c++ - 创建图时内存写入异常

c++ - 如何避免动态分配内存 C++

c++ - 删除导致段错误的 cout 语句

c++ - 为什么这个字符串被神秘地修改了?

c++ - C++ 新手, undefined reference

C 用指针参数定义函数指针

c# - C# Winforms 应用程序中总进程内存使用量的自相矛盾的报告