在返回 + C 的方法中正确使用 free()

  • 本文关键字:free 返回 方法 c malloc free
  • 更新时间 :
  • 英文 :


我的程序中有几个方法,其中我有一个字符*str,我malloc,然后需要在方法结束时返回str。我不知道我需要在这些方法中放置 free() 语句的位置。如果我在返回 str 之前释放(),str 是空的,如果我在返回语句之后这样做,我想它不会在正确的时间被释放吗?例如,如果我在程序被释放之前退出程序,这将产生内存泄漏。正确的方法是什么?

通过阅读您的问题,我认为您对malloc和free的工作原理有错误的理解。

Malloc 将在您的进程堆上分配空间。此堆是全局的,这意味着您可以从代码中的任何位置(而不仅仅是在函数中)访问它。因此,您还可以在代码中的任何位置释放它。如果您返回指向已分配空间的指针,则在同一函数中释放它是没有意义的(否则您有一个悬空指针,即引用已释放空间的指针)。因此,将指针从函数以外的其他任何地方释放是完全可以的(也是必要的)。

此外,正如您所说,您的进程"退出后"不会发生内存泄漏。内存泄漏发生在进程内部;这意味着进程的某些堆被分配,但不再使用(并且没有引用它,因此无法再释放它)。当你的程序占用堆上的大量空间时,这可能会导致内存不足问题(而且这对性能安利不利,所以你永远不希望这种情况发生)。但是,当您的进程退出时,操作系统无论如何都会释放它的所有内存(包括堆)。因此,不再有内存泄漏(除非您正在处理多线程,但这是一个不同的主题)。

如果我

能让我的代码遵循以下模式,我通常会很高兴:

char * foo_allocate() {
    char * s = malloc(10);
    snprintf(s, 10, "hello");
    return s;
}
void foo_release(char *s) {
   free(s);
}
您必须在

不再需要缓冲区内容时释放缓冲区,而不是在之前释放缓冲区。

你的模式是这样的:

char *SomeFunction()
{
   ...
   return malloc(somelength) ;
}
...
char *mychar = SomeFunction() ;
... // deal with the mychar buffer
free(mychar);
...
释放

分配的内存的位置并不重要,只要您不要忘记释放它。在我看来,放置free()的最佳位置是在从函数返回之前,在称为cleanup的标签中。这样,您就不会有内存泄漏,因为如果您确保每个函数都没有内存泄漏,那么您的整个程序就不会有内存泄漏。

你的函数应该看起来像这样:

int func(void)
{
    /* Code that has allocations in it  */
cleanup:
    /* Here you should free all of your allocations */
    return 0;
}

如果您使用的是Linux,则可以使用valgrind以确保没有任何内存泄漏。

这个问题有很多替代方案,这里有一些解决方案:

1-使用一个函数进行分配,另一个函数进行释放,正如比尔·林奇(Bill Lynch)在他的答案中发布的那样。当您使用具有良好实践的结构(创建构造函数和析构函数)时,通常会使用此方法。

2-使用该函数的人负责释放它返回的字符串。

3-您可以将返回值作为参数传递,下面是一个示例:

void foo(char* s) {
    snprintf(s, 10, "hello");
}

请注意,当您想要返回一个退出代码说一切都已写入时,经常使用最后一个解决方案(您会发现许多使用它的函数)。

int foo(char* s) {
        snprintf(s, 10, "hello");
        return 1; // everything went well
}

在使用分配的内存的最高级别函数中,调用 free() 以释放内存。

释放后,将值设置为 NULL 可确保后续使用s不会使用释放的内存。 如果随后未访问该变量,则编译器可能会优化不需要的s = NULL;

char *Allocator() {
   ...
   char *s = malloc(...);
   ...
   return s;
}

void foo() {
  ...
  char *s = Allocator;
  // ... use s
  free(s);
  s = NULL;
  ...
}

相关内容

  • 没有找到相关文章

最新更新