【问题标题】:I allocate memory in function, and return char*, how should I free it?我在函数中分配内存,并返回 char*,我应该如何释放它?
【发布时间】:2015-04-29 09:34:22
【问题描述】:

如果我想在函数中分配内存:

char* allocate() {
    char *cp = (char*)malloc(10);
    ...
    return cp;
}

我可以使用cpmain()返回的内容吗?以及如何释放cp

【问题讨论】:

    标签: c pointers malloc free lifetime


    【解决方案1】:

    我可以在main()中使用cp中返回的内容吗?

    是的,你可以。

    以及如何释放cp?

    使用

    free(cp); // Replace cp with the name of the pointer if you are using it in another function
    


    另外,你should not cast the result of malloc(and family) in C

    【讨论】:

    • 但是 main 的用户如何知道 char* 是动态分配的?如果他不检查函数的代码,会有内存泄漏????
    • @legend0011 ,如果用户没有通过malloc释放分配的内存,那么就会出现内存泄漏。是的,您可以使用 strdup 来执行此操作。 strdupmalloc+strcpy ,仅此而已。
    • @legend0011 :调用代码不应该知道内存是否是动态分配的。相反,您为您的allocate 函数创建一个相应的deallocate 函数,调用代码必须调用该函数。这个deallocate 函数执行free 和/或解除分配对象所需的任何其他操作。
    • 在像 C 这样的语言中,有时需要记录函数,例如返回的指针应该被释放,并信任调用者阅读文档。正如 Sander De Dycker 所说,有时您可以通过将其作为 alloc/dealloc 函数集的一部分来提供帮助,但通常您需要返回 >1 个结果,在这种情况下,没有配对并且您失去了对用户的“提示”无论如何。
    【解决方案2】:

    你应该总是测试malloc(3)的失败,所以至少使用perror(3)exit(3)就像:

      char *cp = malloc(10);
      if (!cp) { perror("malloc"); exit(EXIT_FAILURE); };
    

    一些 Linux 系统正在启用memory overcommit。这是一个肮脏的功能,您应该禁用。

    如果您正在认真编码(例如,一个强大的库供其他人使用),您可能需要提供更复杂的内存不足错误恢复(也许有一个约定,每个分配例程都可以在失败时返回 NULL) . YMMV。

    确实,稍后您需要使用cp 中的指针调用free(3)。如果你不这样做,你将拥有一个memory leak。之后,您将不允许使用,即取消引用该指针(注意pointer aliases)或简单地将其与其他指针进行比较;应该是undefined behavior

    约定关于何时以及谁应该致电free 非常重要。您应该记录该约定。定义和实施此类约定并不总是那么容易。

    在 Linux 上,您可以使用非常有用的工具来帮助解决 C dynamic memory allocation 问题:valgrind,将 -Wall -Wextra -g(用于获取所有警告和调试信息)传递给 GCC 编译器,将 -fsanitize=address 传递给最近的 @987654341 @等

    另请阅读garbage collection;至少要获得一些术语,例如reference counting。在一些 C 应用程序中,您稍后可能想要使用Boehm's conservative GC

    【讨论】:

    • 嗯,我还没有这样做,但我很想只为“至少使用 perror(3) 和 exit(3)”而投反对票,因为图书馆已经击中当他们的库函数出现问题时,他们认为这是一个好主意的函数编写者。
    • @GwynEvans:有一个库函数在内存不足的情况下执行perror 而不是exit通常可以接受的,当然比不检查@的结果更可取987654344@
    【解决方案3】:

    1.我可以在 main() 中使用 cp 中返回的内容吗?

    是的,你可以。动态分配内存(在堆上)的 范围 和生存期不限于函数范围。它在free()d 之前一直有效。

    注意:始终检查 malloc()do not cast 的返回值是否成功。

    2.以及如何释放cp?

    使用完内存后,您可以从main() 或任何其他函数调用free(<pointer>);,其中<pointer> 是您收集allocate() 返回值的变量。

    【讨论】:

    • [这是我今天连续第三次重复我自己 :-)..] 亲爱的投票者,请留言提及投票背后的原因.谢谢你。 :-)
    猜你喜欢
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多