用C编写内存管理函数



在我刚开始的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循环。


最后但并非最不重要的是,内存和许多其他系统一样,是同一系统中的资源。您可以逐个打开文件,然后逐个关闭它们。你一个接一个地得到信号量,然后一个接个地释放它们。你一根接一根地打开管道,然后一根一根地关上。见鬼,你甚至一个接一个地打开{,然后用}一个接地关闭它。为记忆破例是没有意义的。

事实上,一些非常害怕记忆的人过去曾尝试过你的方法。他们称之为垃圾收集器,这是对资源管理规律性的侮辱。(同样的人也非常害怕指针,基本上是编程)

最新更新