没有相应的malloc
的{{1}}总是会产生内存泄漏吗?还是存在某些情况?
答案 0 :(得分:4)
这取决于您如何定义“内存泄漏”。如果您将其定义为在程序退出时具有未分配的具有已分配存储持续时间的对象,那么是的,这是一个泄漏。这就是valgrind报告之类的工具。但是,这根本不是一个有用的定义。
我对内存泄漏的定义是,尽管有一个有限的工作集,但是在程序的整个生命周期中,它的总内存消耗几乎是无限增长的。例如,如果我在浏览器中始终打开至相同的10个站点的最多10个选项卡,但是内存使用无限制地增加,那就是内存泄漏。另一方面,分配缓冲区以将整个文件加载到内存中,加载文件,反向打印它,然后退出而不释放内存的程序不会发生内存泄漏。
一个特别重要的情况是,没有malloc
的{{1}}不仅是泄漏,而且是绝对必要的(对于无法对正在运行的整个程序进行假设的通用代码)是对运行时分配的常量表的任何使用,其生成受free
控制。不管您尝试释放此类表有多晚,代码(在另一个线程或call_once
处理程序等中)都有可能在释放完atexit
类型的接口之后尝试访问它有意地不提供任何方式来同步除第一次调用以外的任何访问(这是它们避免每次读取时引入不必要的获取障碍/同步成本的方式)。
请注意,此处的“工作集”的概念有些主观,并且具有很高的承载能力。通常,内存泄漏是软件在用户不再考虑时仍在考虑其工作集的一部分的问题。
答案 1 :(得分:1)
答案可能取决于malloc
的实现,但是通常在两种情况下,malloc
不会产生内存泄漏:
当您将它作为大小参数传递给0时,某些实现将仅返回NULL
并且不分配任何内容,而其他实现将返回唯一的指针,即使这算作分配的零字节,也会泄漏记账记录中大约有64个字节。
内存不足时。检出全局变量errno
具有特定值,通常使用ENOMEM
来查看它是否失败。在这种情况下,malloc
也会返回NULL
。
答案 2 :(得分:1)
内存泄漏 是一种情况:程序分配了内存,当不再使用它时不释放它,并且失去了对其地址的跟踪(值malloc
,calloc
或realloc
返回的指针的大小。
由于指针丢失,因此无法再释放内存,并且将保持与程序的连接,直到退出为止。
如果程序退出,则与该程序相关的所有内存将被操作系统回收(除非超出本问题范围的罕见情况),因此内存泄漏没有任何后果。
如果该程序执行了很长时间(可能要等到系统关闭后才执行),则附加到该程序的未使用内存块将无法用于其他目的。如果这样浪费的内存量很小,那么不会有任何后果。
相反,如果程序继续分配更多的内存而不释放它,则系统将耗尽该程序使用的内存,并返回NULL
进行分配请求,或者由于使用虚拟内存而变得不稳定满足这些请求的代价是其他程序的代价以及对存储设备或其他压缩技术的长时间交换操作的代价。在某个时候,系统可能会随机终止进程以尝试恢复可用内存。
这类内存泄漏是有问题的,必须避免。它们在库功能中尤其成问题,这些库功能可能用于运行扩展会话的程序中,例如Web浏览器,电子邮件阅读器,文件管理器,媒体播放器,程序管理器...
与其他编程语言不同,C没有嵌入式垃圾收集器可以确定哪些分配的内存块仍在使用中,因此程序员有责任跟踪所有分配的块并尽快释放它们。诸如 valgrind 之类的高级工具可用于验证是否在程序退出时释放了所有分配的块。尽管不必在退出时释放内存,但这是一种良好的编程习惯,也是确定是否已考虑所有分配的内存块的好方法。
答案 3 :(得分:0)
该标准完全不需要内存泄漏。因此,就本质而言,没有任何情况可以保证内存泄漏。
另一方面,在您提到的情况下,该标准也不要求不会发生内存泄漏。
在大多数情况下,程序退出时将释放所有分配的内存。但是某些系统上可能会有例外,尤其是嵌入式系统。如果这对您的程序至关重要,则不应依赖它。