不,终止程序,就像exit
or abort
,不会以与free
. Using free
当操作系统丢弃由malloc
and free
.
exit
有一些复杂性,因为它不会立即终止程序。现在,我们只考虑立即终止程序的影响,稍后再考虑并发症。
In a general-purpose multi-user operating system, when a process is terminated, the operating system releases the memory it was using to make it available for other purposes.1 In large part, this simply means the operating system does some accounting operations.
相反,当您调用free
,程序内的软件运行,它必须查找您正在释放的内存的大小,然后将有关该内存的信息插入到它正在维护的内存池中。可能有数千或数万(或更多)此类分配。释放所有数据的程序可能必须执行数千次调用free
。然而,最终,当程序退出时,所产生的所有变化free
将会消失,因为操作系统将丢弃有关该内存池的所有数据 - 所有数据都位于操作系统不保留的内存页中。
所以,在这方面,您链接到的答案 https://stackoverflow.com/a/6347182/8183900是正确的,调用free
是一种浪费。而且,正如它所指出的,需要遍历程序中的所有数据结构来获取其中的指针,以便可以释放它们指向的内存,这会导致所有这些数据结构在被换出时被读入内存到磁盘。对于大型程序,可能需要大量的时间和其他资源。
另一方面,尚不清楚是否可以轻松避免多次调用free
。这是因为释放内存并不是终止程序必须清理的唯一事情。程序可能想要将最终数据写入文件或将最终消息发送到网络连接。此外,程序可能没有直接建立所有这些上下文。大多数大型程序都依赖于软件层,每个软件包可能都建立了自己的上下文,并且通常没有提供任何方式来告诉其他软件“我想现在退出。完成有价值的上下文,但跳过所有内存释放。”因此,所有所需的清理任务可能与空闲内存任务交织在一起,并且可能没有好方法来理清它们。
通常应编写软件,以便在程序突然中止时不会发生任何可怕的情况(因为这种情况可能是由于断电而发生的,而不仅仅是故意的用户操作)。但即使程序可能能够容忍中止,优雅退出仍然有价值。
回到exit
,调用 Cexit
例程不会立即退出程序。退出处理程序(注册为atexit
) 被调用,流缓冲区被刷新,流被关闭。您调用的任何软件库可能已经设置了自己的退出处理程序,以便它们可以在程序退出时完成。因此,如果您想确保程序中使用的库没有调用free
当你结束程序时,你必须调用abort
, not exit
。但通常更喜欢优雅地结束程序,而不是中止。呼唤abort
不会调用退出处理程序、刷新流、关闭流或执行其他结束代码exit
确实——当程序调用时数据可能会丢失abort
.
Footnote
1 Releasing memory does not mean it is immediately available for other purposes. The specific result of this depends on each page of memory. For example:
- 如果内存与其他进程共享,则它们仍然需要该内存,因此释放此进程使用的内存只会减少使用该内存的进程数量。它不能立即用于任何其他用途。
- 如果内存未被任何其他进程使用,但包含从磁盘上的文件映射的数据,则操作系统可能会在需要时将其标记为可用,但暂时将其保留。这是因为您可能会再次运行相同的程序,如果数据仍在内存中就好了,那么为什么不将其保留在原处以防万一呢?这些数据甚至可能被使用同一文件的不同程序使用。 (例如,许多程序可能使用相同的共享库。)
- 如果内存没有被任何其他进程使用,并且只是被程序用作工作区,而不是从文件映射,那么系统可能会将其标记为立即可用,并且不包含任何有用的内容。