在我开始的C语言程序中,我注意到我自由地调用了很多,所以我想到了一个调用一次函数来释放所有东西。这段代码是一种有效的方法,还是有其他建议可以改进它?
#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 %p\n", 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
答案 0 :(得分:7)
虽然对于一个简单的应用程序来说,这似乎是一个好主意,但实际上并非如此。让我们考虑两种情况:
mm_release
这意味着mm_release
完全没用,浪费时间。几十年前的任何操作系统都会为你清理一下这个记忆。一件一件地做它只是浪费时间。
mm_release
这意味着mm_release
必须是专门的。您在执行期间释放内存,因为您已完成一些内存并且您想要将其还原,以便可以在程序中的其他位置使用它。必须向mm_release
提供有关应该释放什么和不应该释放什么的确切信息。这正是free
所做的。
你可以看到,mm_release
根本没有帮助你。在第一种情况下,它是无用的,你可以简单地摆脱它。在第二种情况下,最好直接使用free
,因为无论如何你都有选择地释放内存。
另请注意,您的方法非常友好。非常友好。
您可能认为mm_release
可以将分配的内存分组到相关集中,您可以通过一次调用释放集合中的所有内存。虽然这个可能看起来很吸引人,但实际上它再次毫无用处。首先,实际上要么你没有很多在语义上相似的内存分配,所以它们可以被分组,或者如果你这样做,那么它们已经被放在一个数组或等价物中。
因此,要么内存集都有单个元素(这意味着你没有通过使用这种方法获得任何东西),或者你只是以一个不必要的复杂库为代价来避免for
循环。
最后但同样重要的是,内存与同类系统中的资源一样多。您逐个打开文件并逐个关闭它们。你逐个获得信号量,然后逐个释放它们。你逐个打开管道然后逐个关闭它们。哎呀,你甚至一个接一个地打开{
并一个接一个地用}
关闭它。对内存进行异常没有意义。
事实上,一些非常害怕记忆的人在过去尝试过你的方法。他们称之为垃圾收集器,这是对资源管理规律性的侮辱。 (那些人也非常害怕指针,基本上都是编程)