没有相应 free 的 malloc 是否总是会产生内存泄漏?

Does malloc without corresponding free always produce a memory leak?

没有相应的 freemalloc 是否总是会产生内存泄漏,或者是否存在不会产生内存泄漏的情况?

答案可能取决于 malloc 的实现,但通常有两种情况 malloc 预计不会产生内存泄漏:

  1. 当您将 0 作为大小参数传递给它时,某些实现将只是 return NULL 而不会分配任何内容,而其他实现将 return 一个唯一指针即使这算作分配的零字节,您仍然会在簿记记录中泄漏大约 64 个字节。

  2. 内存不足时。查看全局变量errno是否有具体值,一般是ENOMEM看是否失败。在这种情况下 mallocreturns NULL 也是如此。

标准根本不需要内存泄漏。所以就其本身而言,没有任何情况可以保证内存泄漏。

另一方面,标准不要求在您提到的情况下不会发生内存泄漏。

在大多数情况下,所有分配的内存都会在程序退出时释放。但在某些系统上可能会有例外,尤其是嵌入式系统。如果这对您的程序至关重要,则不应依赖它。

这取决于你如何定义"memory leak"。如果您将其定义为在程序退出时具有分配存储持续时间的任何未完成对象,那么是的,这是一个泄漏。这就是 valgrind 等工具的报告。但是,这根本不是一个有用的定义。

我对内存泄漏的定义大致是尽管工作集有限,但程序在其生命周期内的总内存消耗无限制地增加。例如,如果我在浏览器中始终最多打开 10 个选项卡,指向相同的 10 个站点,但内存使用量不断增加,这就是内存泄漏。另一方面,分配缓冲区以将整个文件加载到内存中,加载文件,反向打印,然后退出而不释放内存的程序不会发生内存泄漏。

一个特别重要的案例,其中没有 freemalloc 不仅不是泄漏而且是绝对必要的(对于不能对整个程序做出假设的通用代码,它是 运行 in) 是运行时分配的常量表的任何使用,其生成由 call_once 控制。无论您尝试释放此类表的时间有多晚,代码(在另一个线程或 atexit 处理程序等中)都可能在释放后尝试访问它,并且 call_once 类型接口有意不提供任何方式来同步除第一次调用之外的任何访问(这是他们避免在每次读取时引入不必要的获取 barriers/synchronization 成本的方式)。

注意这里"working set"的概念有些主观,承重感很强。内存泄漏通常是软件仍在考虑其工作集的一部分而用户不再考虑它的问题。

A 内存泄漏 是程序分配内存,不再使用时不释放内存的情况,并且失去对其地址的跟踪(指针的值 return 由 malloccallocrealloc 编辑)。

由于指针丢失,内存无法再释放,会一直附着在程序上,直到程序退出。

如果程序退出,所有与之关联的内存都会被操作系统回收(除了超出本题范围的极少数情况),所以内存泄漏没有后果。

如果程序执行很长时间,可能直到系统关闭,附加到程序的未使用内存块不能用于其他目的。如果因此浪费的内存量很小,同样不会产生任何后果。

相反,如果程序一直分配更多内存而不释放它,系统将 运行 内存不足以供程序使用,并且 return NULL 需要分配请求或变得不稳定,因为它使用虚拟内存以其他程序为代价来满足请求,并以对存储设备或其他压缩技术的冗长交换操作为代价。在某些时候,系统可能会随机终止进程以尝试恢复可用内存。

这样的内存泄漏是有问题的,必须避免。它们在可能用于 运行 用于扩展会话的程序中的库函数中尤其有问题,例如网络浏览器、电子邮件阅读器、文件管理器、媒体播放器、程序管理器...

与其他编程语言不同,C 没有嵌入式垃圾收集器来确定哪些已分配的内存块仍在使用中,因此程序员有责任跟踪所有已分配的块并尽快释放它们可能的。 valgrind 等高级工具可用于验证程序退出时是否已释放所有分配的块。虽然没有必要在退出时释放内存,但这是良好的编程习惯,也是确定是否已分配所有内存块的好方法。