我在程序中有几个方法,其中我使用char *str,我对其进行了动态内存分配(malloc),并需要在方法结束时返回str。但是我不知道在这些方法中应该在哪里放置free()语句。如果我在返回str之前释放它,那么str将为空,如果我在return语句之后释放它,它可能会在错误的时间被释放。如果在释放之前退出程序,这将导致内存泄漏。正确的做法是什么?
如果我的代码能够遵循这个模式,我通常会感到非常高兴:
char * foo_allocate() {
char * s = malloc(10);
snprintf(s, 10, "hello");
return s;
}
void foo_release(char *s) {
free(s);
}
asprintf()
非常好用:它会自动为您分配足够的内存。不需要使用固定的缓冲区大小,这样您就不会出错或者随着使用量的增加而变得不足...您还可以提到,应该记录下调用者需要释放缓冲区的信息。 - cmaster - reinstate monica当您不再需要缓冲区的内容时,必须释放该缓冲区,而不是在之前释放。
您的模式应该像这样:
char *SomeFunction()
{
...
return malloc(somelength) ;
}
...
char *mychar = SomeFunction() ;
... // deal with the mychar buffer
free(mychar);
...
这个问题有很多替代方案,以下是一些解决方案:
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
}
malloc()
缓冲区。 - cmaster - reinstate monicafree()
来释放内存。NULL
可以确保后续使用s
不会使用已释放的内存。如果变量没有随后被访问,则编译器可能会优化掉不需要的s = NULL;
。char *Allocator() {
...
char *s = malloc(...);
...
return s;
}
void foo() {
...
char *s = Allocator;
// ... use s
free(s);
s = NULL;
...
}
释放已分配的内存的位置并不重要,只要您不要忘记释放它即可。在我看来,最好的地方是在函数返回之前,在一个名为cleanup的标签中放置free()。
这样,您就不会有内存泄漏问题,因为如果您确保每个函数都没有内存泄漏,那么整个程序也不会有内存泄漏。
您的函数应该像这样:
int func(void)
{
/* Code that has allocations in it */
cleanup:
/* Here you should free all of your allocations */
return 0;
}
free()
之前让程序退出?这不是一个好的设计方法。 - muradin