在C或c++应用程序中出现内存泄漏是可以接受的吗?

如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?只要内存消耗不随时间增长,那么当应用程序终止时(在Windows、Mac和Linux上),是否可以信任操作系统为您释放内存?如果内存一直被使用,直到被操作系统释放,您会认为这是真正的内存泄漏吗?

如果是第三方库将这种情况强加给您,该怎么办?会拒绝使用第三方库,不管它有多好?

我只看到了一个实际的缺点,那就是这些良性泄漏将在内存泄漏检测工具中显示为误报。


当前回答

我相信答案是否定的,永远不要允许内存泄漏,我有一些我没有看到明确说明的原因。这里有很好的技术答案,但我认为真正的答案取决于更多的社会/人类原因。

(首先,请注意,正如其他人所提到的,真正的泄漏是当您的程序在任何时候失去对已分配内存资源的跟踪时。在C语言中,当你malloc()指向一个指针并让该指针离开作用域而没有先执行free()时,就会发生这种情况。

你做决定的关键在于习惯。当你用一种使用指针的语言编写代码时,你会经常使用指针。指针是危险的;它们是向代码中添加各种严重问题的最简单方法。

当你在编程的时候,有时你会很专注,有时你会很累、生气或担心。在那些有点分心的时间里,你会更多地自动编码。自动驾驶效果不会区分一次性代码和大型项目中的模块。在此期间,您所建立的习惯将最终出现在您的代码库中。

所以,不,永远不要允许内存泄漏,就像你在换车道时仍然应该检查盲点一样,即使你是路上唯一的车。当你活跃的大脑分心时,好习惯可以让你避免灾难性的失误。

除了“习惯”问题之外,指针是复杂的,通常需要大量的脑力来在精神上跟踪。当涉及到指针的使用时,最好不要“搅浑水”,特别是当您是编程新手时。

还有更多的社交方面。通过正确使用malloc()和free(),任何查看您的代码的人都会感到轻松;你在管理你的资源。然而,如果你不这样做,他们马上就会怀疑有问题。

也许您已经发现内存泄漏在这种情况下不会造成任何损害,但是代码的每个维护者在阅读这段代码时也必须在自己的头脑中解决这个问题。通过使用free(),您甚至不需要考虑这个问题。

最后,编程是用一种明确的语言编写一个过程的心理模型,这样人和计算机就可以完全理解所述过程。好的编程实践的一个重要部分是永远不要引入不必要的歧义。

智能编程是灵活和通用的。糟糕的编程是模棱两可的。

其他回答

也许是在细枝末节:如果您的应用程序运行在UNIX上,可能会变成僵尸怎么办?在这种情况下,内存不会被操作系统回收。所以我说你应该在程序退出之前重新分配内存。

这实际上取决于创建内存泄漏的对象的使用情况。 如果在使用该对象的应用程序的生命周期内多次创建该对象,那么使用这种方式是不好的。因为会有很多内存泄漏。 另一方面,如果我们有一个对象的实例,不消耗内存,只泄漏少量,那么这不是一个问题。

当应用程序运行时内存泄漏增加时,内存泄漏就是一个问题。

我想以你的情况,答案可能是没关系。但是您肯定需要记录内存泄漏是一个有意识的决定。你不希望一个维护程序员出现,把你的代码放到一个函数中,然后调用它一百万次。因此,如果您决定泄漏是可以接受的,那么您需要为将来可能不得不在该程序上工作的任何人记录它(用大写字母)。

如果这是一个第三方库,你可能会被困住。但是一定要记录泄漏的发生。

但基本上,如果内存泄漏是一个已知的数量,比如512 KB的缓冲区,那么它就不是问题。如果内存泄漏持续增长,比如每次调用库调用时,内存都会增加512KB,但没有释放,那么可能有问题。如果您记录它并控制调用执行的次数,那么它可能是可管理的。但是你真的需要文档,因为虽然512不是很多,但是512超过一百万次调用就很多了。

此外,您还需要检查您的操作系统文档。如果这是一个嵌入式设备,那么操作系统可能不会从退出的程序中释放所有内存。我不确定,也许这不是真的。但这是值得研究的。

这个问题已经讨论得令人作呕了。最重要的是,内存泄漏是一个bug,必须修复。如果第三方库泄露了内存,就会让人怀疑它还有什么问题,不是吗?如果你要造一辆汽车,你会使用一个偶尔漏油的发动机吗?毕竟,引擎是别人做的,所以这不是你的错,你不能修,对吧?

规则很简单:如果你用完了一些内存,就清理它。 有时,即使我们稍后需要一些实例,但我们注意到我们会大量使用内存,所以它会影响性能,因为交换到磁盘,我们可以将数据存储到磁盘文件中,然后重新加载它们,有时这种技术会优化你的程序。