【发布时间】:2016-10-10 16:26:43
【问题描述】:
我们的团队最近开始试验智能指针,我越来越担心我们检测和纠正内存泄漏的能力。
我理解(我认为......)在最纯粹的意义上,智能指针很少有真正的泄漏,如果有的话,它通常与循环引用有关。但是,恐怕这掩盖了“不需要和不必要的内存消耗”意义上的内存泄漏问题。
例如,当使用传统的原始指针时,如果一个对象无法正确清理内存,我们可以运行 Valgrind,然后在程序结束时,剩下的就是一个泄漏(通常这可能是一个继续增长的泄漏在程序执行期间导致严重问题)。 . .现在有了智能指针,这些都在程序退出之前被清理干净,Valgrind 不会看到任何丢失的对分配内存的引用。
总的来说,我看到智能指针在帮助开发人员防止泄漏方面的价值,但是我们是人类并且会犯错误,这就是我们有调试工具的原因!
我们如何检测由于编程错误导致的不必要的内存增长,就像我们过去能够使用 Valgrind 和原始指针一样?
...编辑
1) 愚蠢的是,我通常将 Valgrind 与 Memcheck 联系起来,这就是我打算在上面使用它的方式。我为混乱道歉。
2) 作为一个例子,这里是一个例子:
考虑使用多线程应用程序来处理数据。第一个线程读取输入(从磁盘或网络中),然后通过队列将数据块传递给另一个运行算法步骤 1 的线程,步骤 1 的线程从其输入队列中抓取数据,然后将数据传递给步骤 2。重复直到最后一个线程写出结果(到磁盘或网络)。处理完所有输入数据后,每个线程在完成最后一项并退出程序后都会杀死自己。
现在在执行过程中,我们的足迹显着增长,假设我们可以像摄取数据一样快地处理数据,那么肯定存在泄漏。我使用原始指针来检测这种 Memcheck 错误,它会在程序结束时报告丢失或可能丢失的内存块,我们可以追踪和修复。
3) 在我们匆忙学习和应用智能指针时,我们可能使用了“shared_ptr”,因为另一种类型可能更适合我们的应用程序。
【问题讨论】:
-
我不明白为什么 valgrind 不起作用。如果您有泄漏,则意味着资源不会被自动清理并且应该能够被检测到。
-
因为当智能指针失去作用域时,它会自动销毁自己。当创建它的对象失去作用域时,就会发生这种情况。如果一个对象持续整个运行时(比如一个代表一个线程及其要处理的数据的输入/输出队列)并且由于错误而导致内存消耗增加,智能指针仍然在程序退出时被销毁,而 valgrind 不会注意损失。
-
我不确定智能指针 API 的设置方式是否会发生这种情况。如果你有一个很好看的例子。
-
好的工具不能代替好的工艺。您仍然必须编写合理的代码,这意味着拥有最少的所有权(始终是唯一的,从不共享,除非您更了解)、严格的范围和代码审查。智能指针让你写出好的代码;它们不会神奇地使任意代码变好。
-
写出好的代码始终是我们的目标,但错误总会发生,这就是为什么我们有工具来帮助我们找出错误!
标签: c++ pointers memory memory-leaks