【问题标题】:Return an allocated variable返回分配的变量
【发布时间】:2009-08-20 12:16:35
【问题描述】:

我知道我们应该释放任何用 malloc 分配的变量,但是如果我在函数中返回它呢?像这样的:

char *somefunction(int somearg){
    char *str;

    str=(char *)malloc(sizeof(char *));

    //some code

    return str;
}

我应该释放 str 吗?我怎么能这样做?

【问题讨论】:

  • malloc() 的参数几乎肯定是错误的 - 您分配了足够的内存来存储 char *,但分配给指向 char 的指针(并且无需强制转换malloc 在 C 中的返回值,或者)。 str = malloc(N * sizeof *str); 是一个更好的写法。
  • 正如 CAF 所说,你永远不应该转换 malloc() 的返回值。见stackoverflow.com/questions/1565496/…等人

标签: c malloc


【解决方案1】:

您有两种选择:一,将 char* 传递给 somefunction 并使用它而不是在 somefunction 中分配,或者二,稍后释放返回值。

第一个选项:

char *somefunction(char *str, int somearg){

    //some code

    return str;
}

// Elsewhere...
char *str = (char *) malloc....;
somefunction(str, 123);
// Code...
free(str);

第二个选项:

char *somestr = somefunction(123);
// Do something...
free(somestr);

我个人建议第一个选项,因为当它没有在任意函数中分配时,它更容易避免内存泄漏。

【讨论】:

  • 很好的答案(和问题),我最近偶然发现了同样的问题。一个问题:如果事先很难确定函数的返回值需要多少内存怎么办?那么在函数中进行分配似乎更自然;否则,在提供的内存空间太小(例如,返回可变长度的字符串)的情况下,您需要在函数中进行一些错误处理。
  • 可变长度字符串可以证明在函数内分配内存是合理的。但是,我对自己项目中的此类代码非常犹豫,宁愿明确指定根据上下文和代码要求选择的最大长度。你在说什么类型的可变长度字符串?它们不可能超过可以预分配的几个 KB/MB?
【解决方案2】:

完成后释放它。没有规则说与 malloc() 匹配的 free() 必须在同一个函数中。

【讨论】:

  • 那么,我可以在函数外执行 free(str) 或 free(somefunction) 之类的操作吗?
  • 确实如此。就像你可以使用 malloc() 一样,毕竟它只是另一个函数。
【解决方案3】:

你应该释放所有分配的空间,但如果你返回它,因为你将在程序的其他部分使用这些内存空间,所以在你使用它之后你应该释放它。查看代码中调用函数的每个地方,并在使用返回值后释放空间。

【讨论】:

    【解决方案4】:

    如果您打算返回块的地址,则不应 free() 该块,而应依赖调用代码稍后对其进行 free()。这称为所有权传递。

    如果你在函数中释放它并返回指针,调用代码将在试图访问已经释放的块时遇到未定义的行为。

    【讨论】:

      【解决方案5】:

      这是一些现有功能的做法(例如strdup()),但通常不是一个好主意。要求用户知道函数调用内部发生了什么是一个不好的要求——想想你使用了多少函数,谁的内部是对你隐藏的。 一般来说,您会希望用户传入缓冲区和大小,而不是为他们分配内存。

      【讨论】:

      • 同意,但是如果很难事先决定需要多少空间(例如,动态创建要返回的字符串)。然后,函数根据需要分配尽可能多的内存似乎更自然(也更简单)。你怎么看?
      • 一个很好的观点。然而,实际上,字符串总是有一个已知的上限长度,因为它必须适合数据库字段、屏幕或格式化输出。当然,当您可能只需要一个字节时分配 255 个字节是很浪费的,所以这取决于您要实现的内容。在 Windows 应用程序中我不会太担心,但在 8 位微控制器上的嵌入式系统是不同的花瓶。
      猜你喜欢
      • 2018-06-05
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 2020-01-07
      • 2013-01-15
      • 1970-01-01
      相关资源
      最近更新 更多