在C中编写内存管理功能?

时间:2013-12-11 17:35:47

标签: c memory-management

在我开始的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

1 个答案:

答案 0 :(得分:7)

虽然对于一个简单的应用程序来说,这似乎是一个好主意,但实际上并非如此。让我们考虑两种情况:

1)在程序终止时调用mm_release

这意味着mm_release完全没用,浪费时间。几十年前的任何操作系统都会为你清理一下这个记忆。一件一件地做它只是浪费时间。

2)在{/ h3>之间的某处调用mm_release

这意味着mm_release必须是专门的。您在执行期间释放内存,因为您已完成一些内存并且您想要将其还原,以便可以在程序中的其他位置使用它。必须向mm_release提供有关应该释放什么和不应该释放什么的确切信息。这正是free所做的。


你可以看到,mm_release根本没有帮助你。在第一种情况下,它是无用的,你可以简单地摆脱它。在第二种情况下,最好直接使用free,因为无论如何你都有选择地释放内存。

另请注意,您的方法非常友好。非常友好。


您可能认为mm_release可以将分配的内存分组到相关集中,您可以通过一次调用释放集合中的所有内存。虽然这个可能看起来很吸引人,但实际上它再次毫无用处。首先,实际上要么你没有很多在语义上相似的内存分配,所以它们可以被分组,或者如果你这样做,那么它们已经被放在一个数组或等价物中。

因此,要么内存集都有单个元素(这意味着你没有通过使用这种方法获得任何东西),或者你只是以一个不必要的复杂库为代价来避免for循环。


最后但同样重要的是,内存与同类系统中的资源一样多。您逐个打开文件并逐个关闭它们。你逐个获得信号量,然后逐个释放它们。你逐个打开管道然后逐个关闭它们。哎呀,你甚至一个接一个地打开{并一个接一个地用}关闭它。对内存进行异常没有意义。

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