2016-10-10 292 views
1

我们的团队最近开始尝试使用智能指针,并且越来越担心我们检测和纠正内存泄漏的能力。是否有Valgrind用智能指针检测“内存泄漏”

我明白(我认为......),从最纯粹的意义上说,智能指针很少有真正的泄漏,如果有的话,它通常与循环引用有关。但是,我担心这会掩盖内存泄漏的问题,即“不需要和不必要的内存消耗”。例如,当使用传统的原始指针时,如果一个对象没有正确地清理内存,我们可以运行Valgrind,并且在程序结束时,任何剩下的东西都是泄漏的(通常这可能是一个泄漏,持续到在程序执行期间增长导致严重问题)。 。 。现在使用智能指针,这些全部在程序退出之前得到清理,并且Valgrind不会看到任何丢失的对分配内存的引用。

一般来说,我会看到智能指针在帮助开发人员防止泄漏方面的价值,然而我们是人为的并犯错误,这就是为什么我们有调试工具!

我们如何检测由于编程错误导致的不必要的内存增长,就像我们曾经能够使用Valgrind和原始指针一样?

...编辑

1) 愚蠢我通常与MEMCHECK Valgrind的关联,这就是我打算如何使用上面它。我很抱歉混淆。

2)作为此处的说明是一个例子:

考虑多线程应用程序,以处理数据。第一个线程读取输入(从磁盘或网络),然后将一个数据块传递给另一个线程,通过一个队列运行算法步骤1,Step1的线程从其输入队列中抓取数据,并将数据传递到步骤2。重复,直到最后的线程写出结果(到磁盘或网络)。处理完所有输入数据后,每个线程在完成最后一项并退出程序后自行终止。

现在在执行过程中,我们的脚印显着增长,假设我们可以像接收数据一样快速处理数据,那么必须有泄漏。使用我用来检测这种错误的原始指针与Memcheck,它会在程序结束时报告丢失或可能丢失的内存块,我们可以追踪并修复这些内存块。

3)在我们急于学习和应用智能指针时,我们可能使用“shared_ptr”作为另一种类型,可能更适合我们的应用程序。

+3

我不明白为什么valgrind不会工作。如果您有泄漏意味着资源不会自动清理,并且应该能够被检测到。 – NathanOliver

+0

因为当智能指针丢失范围时它会自动销毁。当创建它的对象失去范围时可能会发生这种情况。如果一个对象持续整个运行时间(如表示一个线程及其输入/输出要处理的数据队列)并且由于错误而导致内存消耗增加,则智能指针在程序退出时仍会被销毁,并且valgrind不会注意损失。 – Toymakerii

+1

我不确定可能会发生智能指针API设置的方式。如果你有一个很好看的例子。 – NathanOliver

回答

2

如果有大量内存增长,你会直接看到或者使用valgrind的massif工具。

还值得注意的是,智能指针有很多种类型。 你提到循环引用,所以大概你在谈论shared_ptr?这是循环引用具有风险的唯一情况 - 对所有智能指针都不是通用的。

一般而言,按优先顺序排列:

  1. 避免(直接)动态分配 - 使用的容器或其他专用类型来管理存储器
  2. 避免复杂的所有权和/或动态分配的资源的寿命: unique_ptr很容易推理
  3. 如果你必须共享所有权,这意味着你的对象生命周期本质上是非确定性的,因此很难推理。但是,你不能漏“共享”对象不泄露它的所有者,所以泄漏意味着一些混乱上涨你的程序结构

    • 请注意,如果您不应该保持一个共享对象活着引用,您应该使用weak_ptr。这也有助于打破静态可预见的周期
+0

我注意到为了清晰和区分我正在寻找的内存泄漏类型的循环引用。这听起来像地块可能是要走的路 – Toymakerii

2

按我的答案c++ char* + std::vector memory leak

有内存泄漏的许多定义 - 和的valgrind不会检测的事情,仍然在范围之内。这是工程师和调试器的工作。 (如果有什么软件可以猜测你什么时候可能决定要使用一些仍在使用范围内的东西?)

+0

这正是我们以前能够用memcheck解决的问题。根据你的链接答案,也许我们应该开始使用Massif来分析堆并手动检测不需要的增长? – Toymakerii

+1

这会检测到它 - 但如果你已经知道你有这个问题,你将不会看到任何新东西。看看单身人士和全局变量,他们是一个很好的起点 – UKMonkey

+0

看起来像Massif提供了一定程度的跟踪分配发生的地方,这应该相当于memcheck的“track-origins”,我们会给出这个镜头! – Toymakerii

1

一个你必须要知道的智能指针的事情是,类之间的循环依赖控股例如彼此的std::shared_ptr<>将不会被正确清理。

恐怕这是valgrind没有发现的情况。

虽然这样可以使用std::weak_ptr<>解决。

+0

这就是为什么弱基准存在:) – UKMonkey

+0

@UKMonkey当然。这是解决这类问题的一种方法。 –