我有一个程序,我使用很多malloc(和其他类似的函数)来为不同的数据类型分配内存。我们知道这个功能可能会失败。如何编写一个简洁的代码来检查内存是否已成功分配,如果没有,则释放所有以前的malloc,如果有的话?
我想可能会编写一个函数来释放每个指针我malloc,如果它们是!= NULL。但后来我需要发送很多参数。 有更好的想法吗?
感谢。
答案 0 :(得分:2)
这实际上是一个非平凡的C编码习语问题。一个答案是学习C ++并使用auto_pointer
。
在C中,我成功地使用了以下习语。
NULL
。goto
标签。return
)。最终看起来像这样:
int err = 0;
FOO *p = NULL;
BAR *q = NULL;
BAZ *r = NULL;
p = malloc(...);
if (!p) {
err = P_MALLOC_FAILURE;
goto done;
}
....
q = malloc(...);
if (!q) {
err = Q_MALLOC_FAILURE;
goto done;
}
....
// Done with p. Free it early.
free(p);
p = NULL;
....
done:
free(p);
free(q);
return err;
free
的定义确保如果指针在结尾处仍为NULL,则不会发生任何事情。如果您不喜欢重复的代码,则可以滥用宏:
#define ALLOC_OR_FAIL(P) do { \
P = malloc(sizeof *P); \
if (!P) { \
err = P ## _MALLOC_FAILURE; \
goto done; \
} } while (0)
答案 1 :(得分:0)
好吧,你可以设计你的代码,如果有错误,那么你的程序流就可以回到调用堆栈,所有函数在返回错误条件时释放它们分配的内存。
如果您的代码组织得不好,那么“整齐地”释放所有以前的mallocs的唯一便携方式是,如果您存储了mallocs的全局表,那么每次调用时都要保持最新状态malloc
或free
(或任何其他分配功能)。
但是,现代操作系统在进程退出时为您释放所有内存,实际上它们可以比您更快地执行此操作,因为它们可以一次性释放整个进程的内存分配。恕我直言,一个实际的决定是在没有明确释放的情况下退出,除非你怀疑你的代码将在一个会泄漏内存的系统上运行。
答案 2 :(得分:0)
就像pzaenger说的那样......
ptr = calloc/malloc/realloc(parameters);
if(ptr == NULL)
{
printf("Well shucks...");
}
足够简单。
我一直在构建一些代码,目前我也有很多参数7/8,其中大多数是被解除引用的指针等等。
我有一些功能,还有更多功能,使用这些相同的7/8参数。所以为了清理它们,我只是将它们填充到一个结构(c struct)中。这样,我所要做的就是传递一个参数,即struct(或者很可能是一个ptr到struct)。
现在你需要做的就是结构的malloc / calloc内存,然后是结构内任何指针的malloc / calloc内存。
然后你来回传递那个结构,做你需要做的任何事情。
最后,您将浏览结构并释放其中的任何内存malloc / calloc。然后释放内存(如果使用了结构的ptr),用于结构本身。