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

时间:2014-11-21 19:59:22

标签: c malloc free

我的程序中有几个方法,我有一个char * str,我是malloc,然后需要在方法结束时返回str。我不知道在哪里需要将free()语句放在这些方法中。如果我在返回str之前我是free(),那么str是空的,如果我在return语句之后执行它,那么我猜它在合适的时间没有被释放?如果我是在程序释放之前退出程序,这将造成内存泄漏。这样做的正确方法是什么?

6 个答案:

答案 0 :(得分:2)

如果我能让我的代码遵循这种模式,我常常很高兴:

char * foo_allocate() {
    char * s = malloc(10);
    snprintf(s, 10, "hello");
    return s;
}

void foo_release(char *s) {
   free(s);
}

答案 1 :(得分:1)

当你不再需要它的内容时,你必须释放缓冲区。

你的模式是这样的:

char *SomeFunction()
{
   ...
   return malloc(somelength) ;
}

...
char *mychar = SomeFunction() ;
... // deal with the mychar buffer

free(mychar);
...

答案 2 :(得分:1)

从阅读你的问题开始,我认为你对malloc和free的运作方式有一个错误的理解。

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

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

答案 3 :(得分:0)

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

你的功能看起来应该是这样的:

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

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

答案 4 :(得分:0)

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

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
}

答案 5 :(得分:0)

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

免费后,将值设置为NULL可确保s的后续使用不会使用免费内存。如果随后没有访问该变量,那么编译器可能会对不需要的s = NULL;进行优化。

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


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