注意:这听起来可能很愚蠢。我有一个使用原始指针的应用程序,该应用程序中有很多内存泄漏。
现在我的问题是,用智能指针替换现有的原始指针有多容易。替换它们将有助于减少由于不释放动态分配的内存而导致的内存泄漏。
为了进一步解释,这个应用程序是一个遗留的应用程序,有非常简单的内存泄漏,内存将被分配,而不是在相同的函数本身中释放。
我用DevPartner做了一个内存分析,发现了很多地方。Valgrind是否比Devpartner更好。
发布于 2010-08-03 21:36:53
使用智能指针当然是清理应用程序的良好开端,但它们不是万能的。在一个原本设计良好的程序中,大量的内存泄漏可能只是粗心大意,但更有可能的是你有重大的设计问题,而内存泄漏就是这种问题的症状。当您切换到智能指针时,您仍然需要做出设计选择,如“谁拥有此对象”、“此对象的所有权是否在多个客户端之间共享”以及“此对象的预期生存期是多少”,以便为给定的方案选择适当的智能指针实现。但这将是一个很好的开始,因为为不同的情况选择适当风格的智能指针的过程将迫使您考虑这些事情,并可能改进您的设计。
发布于 2010-08-03 22:07:36
毫无疑问,智能指针减少了程序员在内存所有权问题上的很多负担。既然您没有提到这是否是一个遗留的应用程序,或者更改接口有多容易(并不总是需要的,因为智能指针会降级为原始指针),我建议您在valgrind (在Linux上)或purify (在Unices和Windows上)这样的工具下运行您的应用程序,以跟踪内存泄漏。
根据我的经验,大多数内存泄漏都遵循一定的模式(开发人员A遗漏了一些东西,开发人员B复制了代码,随之而来的是问题)。因此,使用工具可以先解决内存泄漏问题,然后再考虑使用智能指针。
如果你开始开发这个应用程序--从使用智能指针开始。它们将为您节省大量的时间和精力。
发布于 2010-08-03 22:39:14
我会给出一个“非常有可能”的结论。
内存泄漏的一种形式是当一个函数分配内存,但没有在函数外的至少一个路径中删除它。某些类型的作用域指针,如auto_ptr,可以很好地处理这一点。(注意:auto_ptr是第一个国际标准化组织标准的一部分,在下一个标准中将被弃用,所以很难给出使用哪个作用域指针的建议。请查阅您的编译器和库文档,了解它们支持什么。)
另一种形式是对象被分配的地方,所有权是共享的,这意味着有不止一个例程使用它,没有简单的方法来判断每个人是否都用完了它。这是shared_ptr的一个很好的候选者,但您必须小心。在创建对象时为shared_ptr赋值,并确保使用的其他指针都是shared_ptr。如果例程A、B和C通过shared_ptr访问对象,并且您没有更改D,那么当例程A、B和C完成它时,它就会消失,而不管D的需求如何。
使用shared_ptr时要避免的一件事是循环,因为如果我有一个指向J的shared_ptr,J有一个指向K的shared_ptr,而K有一个指向I的shared_ptr,那么这些都不会被删除,即使在程序中的任何其他地方都无法到达。您需要注意这些情况。您可以在循环中使用weak_ptr来分解它们,或者自己删除循环中的元素,或者只是忍受泄漏。
要考虑的另一件事是用vector和类似的容器替换动态分配的数组和其他动态分配的数据结构。这为您提供了大量免费的内存管理,尽管您仍然可以泄漏内存。如果一个向量变大,然后变小,它不会释放额外的内存。通常的做法是,如果您确实需要回收内存,则使用其自身的副本对曾经很大的向量执行swap操作。
简而言之,有很多非常有用的工具可以自动化大量的内存管理,但它们不会取代您的思考。只需将每个指针转换为shared_ptr,将每个数组转换为vector,就可以解决许多问题,但明智地使用这些方法将带来更大的好处。
https://stackoverflow.com/questions/3396939
复制相似问题