我们都被教导必须释放每个已分配的指针。不过,我有点好奇不释放内存的真正代价。在一些明显的情况下,比如在循环内部或线程执行的一部分调用malloc()时,释放是非常重要的,这样就不会有内存泄漏。但是考虑下面两个例子:
首先,如果我有这样的代码:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
真正的结果是什么?我的想法是进程死亡,然后堆空间也消失了,所以错过对free的调用没有什么坏处(然而,我确实认识到无论如何拥有它对于闭包、可维护性和良好实践的重要性)。我这样想对吗?
Second, let's say I have a program that acts a bit like a shell. Users can declare variables like aaa = 123 and those are stored in some dynamic data structure for later use. Clearly, it seems obvious that you'd use some solution that will calls some *alloc function (hashmap, linked list, something like that). For this kind of program, it doesn't make sense to ever free after calling malloc because these variables must be present at all times during the program's execution and there's no good way (that I can see) to implement this with statically allocated space. Is it bad design to have a bunch of memory that's allocated but only freed as part of the process ending? If so, what's the alternative?
我完全不同意那些说OP是正确的或没有伤害的人。
每个人都在谈论现代和/或传统的操作系统。
但是如果我在一个没有操作系统的环境中呢?
哪里什么都没有?
想象一下,现在您正在使用线程样式的中断并分配内存。
在C标准ISO/IEC:9899中,内存的寿命表示为:
7.20.3 Memory management functions
1 The order and contiguity of storage allocated by successive calls to the calloc,
malloc, and realloc functions is unspecified. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an allocated object extends
from the allocation until the deallocation.[...]
所以我们不能认为环境在为你做释放的工作。
否则,它将被添加到最后一句:“或直到程序终止。”
换句话说:
不释放内存不仅仅是不好的做法。它生成不可移植且不符合C的代码。
至少可以被视为“正确的”,如果有以下情况:[…]],由environment支持。
但如果你根本就没有操作系统,那就没有人在为你做这项工作了
(我知道通常在嵌入式系统中不会分配和重新分配内存,
但在某些情况下,你可能想这么做。)
在普通的C语言中(OP被标记)
这只会产生错误的和不可移植的代码。
真正的结果是什么?
你的程序泄露了内存。根据您的操作系统,它可能已经恢复。
大多数现代桌面操作系统确实会在进程终止时恢复泄漏的内存,这使得忽略这个问题变得很常见(从这里可以看到许多其他答案)。
但是您依赖的是一个不属于该语言的安全特性,您不应该依赖它。您的代码可能运行在这样一个系统上,该行为下次会导致“硬”内存泄漏。
你的代码最终可能会在内核模式下运行,或者在老式/嵌入式操作系统上运行,这些操作系统不采用内存保护作为权衡。(mmu占用芯片空间,内存保护成本额外的CPU周期,并且要求程序员自己清理并不过分)。
您可以以任何您喜欢的方式使用和重用内存(和其他资源),但请确保在退出之前释放了所有资源。