我们的团队最近开始尝试智能指针,我越来越关注我们检测和纠正内存泄漏的能力。
我理解(我认为......)在最纯粹的意义上,智能指针很少有真正的泄漏,如果存在,它通常与循环引用相关。但是,我担心这会掩盖内存泄漏的问题,因为它会导致不必要的和不必要的内存消耗。#34;
例如,当使用传统的原始指针时,如果一个对象无法正确清理内存,我们可以运行Valgrind,在程序结束时,剩下的任何东西都是泄漏(通常这可能是一个持续增长的泄漏在程序执行期间导致严重问题)。 。 。现在有了智能指针,这些都会在程序退出之前得到清理,Valgrind也不会看到任何丢失的对已分配内存的引用。
总的来说,我看到了智能指针在帮助开发人员防止泄漏方面的价值,但是我们是人类并且犯了错误,这就是为什么我们有调试工具!
我们如何检测由于编程错误导致的不必要的内存增长,就像我们以前能够使用Valgrind和原始指针一样?
...编辑
1) 愚蠢的是,我通常将Valgrind与Memcheck联系起来,这就是我打算在上面使用它的方式。我为混乱道歉。
2)这里的例子是一个例子:
考虑使用多线程应用程序来处理数据。第一个线程读取输入(从磁盘或网络无论如何),然后通过队列将数据块传递给运行算法步骤1的另一个线程,Step1的线程从其输入队列中获取数据并执行其操作并传递数据到Step2。重复,直到最后一个线程写出结果(到磁盘或网络)。当处理完所有输入数据后,每个线程在完成最后一个项目并退出程序后自行终止。
现在在执行期间,我们的足迹显着增长,假设我们可以像我们一样快速地处理数据,那么必定会有泄漏。使用原始指针我曾经用Memcheck检测到这种错误,它会在程序结束时报告丢失或可能丢失的内存块,我们可以追踪并修复。
3)我们急于学习和应用智能指针,我们可能会使用" shared_ptr"另一种类型可能更适合我们的应用。
答案 0 :(得分:2)
根据我在c++ char* + std::vector memory leak
中的回答内存泄漏的定义很多 - 而valgrind也不会检测仍在范围内的内容。这是工程师和调试人员的工作。 (当你决定使用仍在范围内的东西时,任何软件如何猜测?)
答案 1 :(得分:2)
如果内存增长显着,您可以直接看到或使用valgrind的块状工具。
还值得注意的是,智能指针有很多种类型。
你提到循环引用,所以大概是你在谈论shared_ptr
?这是循环引用存在风险的唯一情况 - 它对所有智能指针都不通用。
一般来说,按优先顺序排列:
unique_ptr
很容易推理如果必须共享所有权,则意味着您的对象生命周期本质上是非确定性的,因此很难推理。但是,您无法泄漏“共享”#34;对象没有泄露其所有者,因此泄漏意味着一些混乱更高的程序结构
weak_ptr
代替。这也有助于打破静态可预测的周期答案 2 :(得分:1)
使用智能指针必须注意的一件事是,类之间存在循环依赖关系。彼此的std::shared_ptr<>
将无法正确清理。
我担心valgrind没有发现这种情况。
虽然可以使用std::weak_ptr<>
解决此问题。