我们都被教导必须释放每个分配的指针。不过,我有点好奇不释放内存的实际成本。在一些明显的情况下,例如在malloc()循环或线程执行的一部分中调用时,释放非常重要,因此不会出现内存泄漏。但请考虑以下两个示例:
malloc()
首先,如果我有这样的代码:
int main() { char *a = malloc(1024); /* Do some arbitrary stuff with 'a' (no alloc functions) */ return 0; }
这里的真正结果是什么?我的想法是进程死了,然后堆空间无论如何都消失了,所以错过调用没有什么坏处free(但是,我确实认识到无论如何都有它对于关闭、可维护性和良好实践的重要性)。我的这个想法是对的吗?
free
其次,假设我有一个有点像 shell 的程序。用户可以声明变量aaa = 123,这些变量存储在一些动态数据结构中供以后使用。显然,很明显您会使用一些会调用某些 *alloc 函数(哈希映射、链表等)的解决方案。对于这种程序,调用后释放是没有意义的,malloc因为这些变量必须在程序执行期间始终存在,并且没有好的方法(我可以看到)用静态分配的空间来实现它。分配一堆内存但仅作为进程结束的一部分释放是不是糟糕的设计?如果是这样,有什么替代方案?
aaa = 123
malloc
几乎每个现代操作系统都会在程序退出后恢复所有分配的内存空间。我能想到的唯一例外可能是 Palm OS,其中程序的静态存储和运行时内存几乎相同,因此不释放可能会导致程序占用更多存储空间。(我只是在这里推测。)
因此,一般来说,它没有任何害处,除了存储空间超过您需要的运行时间成本。当然,在您给出的示例中,您希望保留可能使用的变量的内存,直到它被清除。
但是,当您不再需要它时立即释放内存并在程序退出时释放您仍然存在的任何内容,这被认为是一种很好的风格。这更像是一种了解您正在使用的内存的练习,并考虑您是否仍然需要它。如果你不跟踪,你可能有内存泄漏。
另一方面,在退出时关闭文件的类似警告会产生更具体的结果——如果你不这样做,你写给它们的数据可能不会被刷新,或者如果它们是临时文件,它们可能不会完成后被删除。此外,数据库句柄应该提交它们的事务,然后在你完成它们时关闭它们。同样,如果您使用的是 C++ 或 Objective C 等面向对象的语言,则在完成对象后不释放对象将意味着永远不会调用析构函数,并且该类负责的任何资源都可能不会被清理。