我怎么知道谁拥有shared_ptr <>?

use*_*749 11 c++ boost memory-leaks shared-ptr

我在C++的应用程序中使用boost :: shared_ptr.内存问题非常严重,应用程序占用大量内存.

但是,因为我将每个新建对象放入shared_ptr,当应用程序退出时,不会检测到内存泄漏.

必须有一些像std::vector<shared_ptr<> >池持有资源的东西.调试时如何知道谁拥有shared_ptr?

很难逐行检查代码.代码太多......

非常感谢!

小智 21

你只能看一下shared_ptr"兄弟指针"的位置,你无法知道.您可以测试如果一个人unique()或获取use_count(),除其他方法.


小智 12

广泛使用的shared_ptr几乎不可避免地会导致不必要的和看不见的内存占用.

循环引用是一个众所周知的原因,其中一些可能是间接的,很难发现,特别是在由多个程序员处理的复杂代码中; 程序员可能决定一个对象需要引用另一个对象作为快速修复,并且没有时间检查所有代码以查看他是否正在关闭一个循环.这种危害被严重低估了.

不太了解的是未公开的参考文献的问题.如果一个对象被共享给许多shared_ptrs,那么在它们中的每一个被归零或超出范围之前它都不会被销毁.很容易忽略其中一个引用,并最终得到你认为已经完成的内存中看不见的对象.

虽然严格来说这些不是内存泄漏(它将在程序退出之前全部释放),但它们同样有害且难以检测.

这些问题是权宜的虚假声明的结果:1.声明你真正希望成为shared_ptr的单一所有权.scoped_ptr是正确的,但是对该对象的任何其他引用都必须是一个原始指针,可以留下悬空.2.声明你真正想要成为被动观察引用的是shared_ptr.weak_ptr是正确的,但是每次你想使用它时你都有把它转换成share_ptr的麻烦.

我怀疑你的项目是这种做法可以让你进入的那种麻烦的一个很好的例子.

如果您有一个内存密集型应用程序,您确实需要单一所有权,以便您的设计可以显式控制对象生存期.

单一所有权opObject = NULL; 肯定会删除该对象,它现在就会这样做.

使用共享所有权spObject = NULL; ........谁知道?......

  • 在现实世界中很多项目都没有设计文档的概念:) (7认同)
  • 代码肯定会误导!制作一个写得很好的软件并不是一件容易的事,而且在保持质量的同时改变现有系统甚至更难(或者我应该说,需要不断的努力).但是评论和文档不能编译,并且通常是与他们试图描述的事物的功能不同步的第一件事.当然,变量名称和函数名称的命名很差,但在我职业生涯中遇到的代码库中似乎不太常见.通常,设计文档是在代码之前编写的,永远不会更新. (5认同)
  • @curiousguy我更喜欢代码来设计文档,因为文档可以说谎,代码编译. (4认同)

ver*_*lop 7

我们已经完成的悬空或循环智能指针引用的一种解决方案是自定义智能指针类以添加仅调试的簿记功能.每当一个智能指针添加一个对象的引用时,它会采用堆栈跟踪并将其放入一个地图中,每个条目都跟踪一个

  1. 被分配对象的地址(指针指向的对象)
  2. 每个智能指针对象的地址,包含对象的引用
  3. 构建每个智能指针时的相应堆栈跟踪

当smartpointer超出范围时,它在地图中的条目将被删除.当对象的最后一个smartpointer被破坏时,指针对象将其地图中的条目删除.

然后我们有一个带有两个函数的"track leaks"命令:'[re]启动泄漏跟踪'(清除整个地图并启用跟踪,如果还没有),'print open references',显示所有未完成的智能指针引用自从'start leak tracking'命令发布以来.由于您可以看到这些智能指针所在的堆栈跟踪,因此您可以轻松地确切知道谁将保留您的对象.当它打开时它会减慢速度,所以我们不会一直保持这种状态.

这是一项相当多的工作要实现,但如果你有一个代码库,这种情况发生了很多,那绝对是值得的.