在我刚开始的C语言程序中,我注意到我经常调用free,所以我想做一个一次性调用的函数来释放所有东西。这个代码是一种有效的方法吗?或者有其他改进建议吗?
#include <stdio.h>
#include <stdlib.h>
void *items_to_free[1024];
int intItemsToFree = 0;
void mm_init(void)
{
int i;
for (i = 0; i < 1024; i++)
{
items_to_free[i] = NULL;
}
}
void mm_release(void)
{
int i;
for (i = 0; i < 1024; i++)
{
if (items_to_free[i])
{
printf("Freeing %pn", items_to_free[i]);
free(items_to_free[i]);
items_to_free[i] = NULL;
}
}
}
void mm_add(void *p)
{
items_to_free[intItemsToFree++] = p;
}
int main(void)
{
int *i = NULL;
/* initialize memory management */
mm_init();
/* allocate something */
i = (int *) malloc(sizeof(int) * 10);
/* add it to the memory collection */
mm_add(i);
/* run program as usual */
printf("App doing something...");
/* at the end, free all memory */
mm_release();
return 0;
}
输出:
App doing something...Freeing 0x100103b30
对于一个简单的应用程序来说,这似乎是个好主意,但实际上并非如此。让我们考虑两种情况:
1) 程序终止时调用mm_release
这意味着mm_release
是完全无用的并且是浪费时间。几十年前的任何操作系统都会一大口为你清理内存。一件一件地自己做只是浪费时间。
2) mm_release
在两者之间调用
这意味着mm_release
必须是专门化的。您在执行过程中释放内存,因为您已经用完了一些内存,并且希望将其归还,以便在程序中的其他地方使用。mm_release
必须得到关于哪些应该发布,哪些不应该发布的确切信息。这正是free
所做的。
所以,正如你所看到的,mm_release
对你没有任何帮助。在第一种情况下,它是无用的,你可以简单地将其清除。在第二种情况中,你最好直接使用free
,因为你无论如何都是有选择地释放内存。
还请注意,您的方法对线程非常友好。
您可能认为mm_release
可以将分配的内存分组到相关的集合中,在这些集合中,您可以通过一次调用释放集合中的所有内存。虽然这个看起来很有吸引力,但在现实中它同样毫无用处。首先,在现实中,要么你没有很多语义相似的内存分配,所以它们可以分组,要么如果你这样做了,那么它们已经被放在一个数组或等效数组中了。
因此,内存集要么只有单个元素(这意味着使用此方法不会获得任何好处),要么只是以不必要的复杂库为代价避免了for
循环。
最后但并非最不重要的是,内存和许多其他系统一样,是同一系统中的资源。您可以逐个打开文件,然后逐个关闭它们。你一个接一个地得到信号量,然后一个接个地释放它们。你一根接一根地打开管道,然后一根一根地关上。见鬼,你甚至一个接一个地打开{
,然后用}
一个接地关闭它。为记忆破例是没有意义的。
事实上,一些非常害怕记忆的人过去曾尝试过你的方法。他们称之为垃圾收集器,这是对资源管理规律性的侮辱。(同样的人也非常害怕指针,基本上是编程)