【问题标题】:Proper Way to Free Memory of a Returned Variable释放返回变量内存的正确方法
【发布时间】:2015-06-21 16:46:08
【问题描述】:

我创建了一个旨在获取用户输入的函数。它要求将内存分配给保存用户输入的变量;但是,该变量在函数末尾返回。释放分配的内存/返回变量值的正确方法是什么?

代码如下:

char *input = malloc(MAX_SIZE*sizeof(char*));
int i = 0;
char c;

while((c = getchar()) != '\n' && c != EOF) {
    input[i++] = c;
}

return input;

输入的地址用完后是否应该返回并释放?

很好奇释放输入变量的最合适方法。

【问题讨论】:

  • 如果你malloc,最终会有人需要free,无论是你在另一个api还是调用者。相关的,如果在您的目标平台上受支持,getline,一个添加到 POSIX.1-2008 的库函数,似乎几乎做你想要实现的事情。它仍然需要调用者最终free 任何返回的分配,但还提供重用语义,您的代码。根据预期用途和目标平台,可能值得考虑。

标签: c memory malloc free


【解决方案1】:

很简单,只要将malloc()返回的指针传递给free()就可以了。

例如

char *readInput(size_t size)
 {
    char *input;
    int   chr;
    input = malloc(size + 1);
    if (input == NULL)
        return NULL;
    while ((i < size) && ((chr = getchar()) != '\n') && (chr != EOF))
        input[i++] = chr;
    input[size] = '\0'; /* nul terminate the array, so it can be a string */
    return input;
 }

 int main(void)
  {
     char *input;
     input = readInput(100);
     if (input == NULL)
         return -1;
     printf("input: %s\n", input);
     /* now you can free it */
     free(input);
     return 0;
  }

你不应该做的事情是这样的

free(input + n);

因为input + n不是malloc()返回的指针。

但是您的代码还有其他问题需要注意

  1. 您正在为MAX_SIZE chars 分配空间,因此您应该乘以sizeof(char),即1,而不是sizeof(char *),后者将分配MAX_SIZE 指针,您还可以使MAX_SIZE 改为函数参数,因为如果要分配固定缓冲区,则可以在 main() 中定义大小为 MAX_SIZE 的数组,如 char input[MAX_SIZE],并将其作为参数传递给 readInput(),从而避免 @ 987654338@和free()

  2. 您分配了那么多空间,但您没有防止 while 循环中的溢出,您应该验证 i &lt; MAX_SIZE

【讨论】:

  • 他不能使用本地数组,因为当它返回并且函数的堆栈帧被破坏时,无法保证数组完好无损。编译器会给你一个警告:“函数返回局部变量的地址 [-Wreturn-local-addr]”。除此之外,很好的答案。
  • @EnzoFerber 我的意思是将数组传递给函数并在那里填充,我知道你不能返回本地数组。我想我需要澄清一下。
  • 很好的例子。谢谢。
【解决方案2】:

您可以编写一个返回类型为char* 的函数,返回input,并要求用户在处理完数据后调用free

您也可以要求用户自己传入一个适当大小的缓冲区,连同缓冲区大小限制,并返回写入缓冲区的字符数。

【讨论】:

    【解决方案3】:

    这是一个经典的 c 案例。函数 malloc 为其结果分配内存,调用者必须释放返回值。您现在正走在c 内存泄漏的薄冰上。 2 个原因

    首先;您无法以可执行的方式传达免费要求(即编译器或运行时无法帮助您 - 与指定参数类型相比)。您只需在某处记录它并希望调用者已阅读您的文档

    第二:即使调用者知道释放结果他可能会犯错误,也会采取一些不释放内存的错误路径。这不会立即导致错误,似乎一切正常,但运行 3 周后,您的应用在内存不足后崩溃

    这就是为什么这么多“现代”语言都关注这个主题的原因,c++ 智能指针、Java、C# 等垃圾回收......

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多