首页 > 解决方案 > malloc后如何释放空间?

问题描述

所以我目前正在使用一种方法,我必须分配空间来制作对象。任何人都知道当我想结束程序时如何释放方法中的空间。现在,当我尝试腾出空间时,我不断收到内存错误。

struct linkedlist *newNode(int val) { 
    struct linkedlist *node = (struct linkedlist *)malloc(sizeof(struct linkedlist)); 
    node->data = val; 
    node->next = NULL; 

    return node; 
}

标签: cmallocfree

解决方案


显而易见的答案太明显了;所以我假设你需要一个“不太明显”的答案。我能想到两件事。

释放整个链表(不仅仅是一个节点)

您要确保在释放内存后不使用内存。对于链表,这意味着您不应该这样做:

    while(node != NULL) {
        free(node);
        node = node->next;   // BUG
    }

为避免此问题,您应该使用临时变量,如下所示:

    while(node != NULL) {
        temp = node->next;
        free(node);
        node = temp;
    }

退出前释放

对于大多数操作系统,都有内存管理层(堆、虚拟页面和虚拟地址空间的管理、物理 RAM 的管理)。当您从堆中释放内存free()(堆。

当您的程序退出(或崩溃)时,操作系统必须清理它正在使用的资源,包括销毁/取消分配您的程序正在使用的整个虚拟地址空间及其包含的所有内容(包括堆上的任何内容)不是免费的free())。因为这是使用“批发”方法(而不是“零碎”方法)完成的,并且因为它是在较低级别完成的(绕过堆管理的开销),并且因为它是由内核本身完成的(绕过系统成本)跨越用户空间和内核空间之间障碍的调用和转换),并且因为它无论如何都必须发生(不管你是否free());在程序退出之前不用费心释放堆上的任何东西,它可以显着更快并且同样有效。

退出前内存的主要原因free()是检测内存泄漏 - 仍然分配的任何内容(在您尝试释放所有内容之后)都是您的程序丢失的内存。然而,大多数人不会在他们的软件中构建这些类型的检查,如果他们这样做,很容易使其成为可选的(例如,使用“ #ifdef MEM_LEAK_TEST_AT_EXIT”,因此可以在测试期间启用它,但在发布时禁用它)。


推荐阅读