问题标签 [smart-pointers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 查找由智能指针引起的内存泄漏
有人知道发现智能指针引起的内存泄漏的“技术”吗?我目前正在开发一个用C++编写的大型项目,该项目大量使用带有引用计数的智能指针。显然,我们有一些由智能指针引起的内存泄漏,它们仍然在代码中的某处被引用,因此它们的内存不会被释放。很难找到带有“不必要”引用的代码行,这会导致相应的对象不被释放(尽管它不再使用)。
我在网上找到了一些建议,建议收集引用计数器的递增/递减操作的调用堆栈。这给了我一个很好的提示,哪段代码导致引用计数器增加或减少。
但我需要的是某种算法,将相应的“增加/减少调用堆栈”组合在一起。删除这对调用堆栈后,我希望(至少)剩下一个“增加调用堆栈”,它向我展示了带有“不必要”引用的代码段,导致相应的对象未被释放。现在修复泄漏没什么大不了的!
但是有人对进行分组的“算法”有想法吗?
开发在Windows XP下进行。
(我希望有人理解,我试图解释的......)
编辑:我说的是循环引用引起的泄漏。
c++ - 智能指针:谁拥有对象?
C++ 是关于内存所有权的——也就是所有权语义。
一块动态分配的内存的所有者有责任释放该内存。所以问题真的变成了谁拥有记忆。
在 C++ 中,所有权由包装在内部的原始指针的类型记录,因此在一个好的(IMO)C++ 程序中,很少(很少,不是从不)看到传递的原始指针(因为原始指针没有推断的所有权,因此我们可以不知道谁拥有内存,因此如果不仔细阅读文档,您就无法知道谁负责所有权)。
相反,很少看到原始指针存储在一个类中,每个原始指针都存储在其自己的智能指针包装器中。(注意:如果您不拥有一个对象,则不应存储它,因为您不知道它何时会超出范围并被销毁。)
所以问题:
- 人们遇到了什么类型的所有权语义?
- 使用哪些标准类来实现这些语义?
- 你觉得它们在什么情况下有用?
让我们为每个答案保留一种语义所有权,以便可以单独对它们进行上下投票。
概括:
从概念上讲,智能指针很简单,简单的实现也很容易。我见过许多尝试的实现,但它们总是以某种方式被破坏,这对于随意使用和示例来说并不明显。因此,我建议始终使用库中经过良好测试的智能指针,而不是自己滚动。std::auto_ptr
或者 Boost 智能指针之一似乎可以满足我的所有需求。
std::auto_ptr<T>
:
单身人士拥有该物品。允许转让所有权。
用法:这允许您定义显示所有权显式转移的接口。
boost::scoped_ptr<T>
单身人士拥有该物品。不允许转让所有权。
用法:用于显示明确的所有权。对象将被析构函数或显式重置时销毁。
boost::shared_ptr<T>
( std::tr1::shared_ptr<T>
)
多重所有权。这是一个简单的引用计数指针。当引用计数达到零时,对象被销毁。
用法:当一个对象可以有多个生命周期无法在编译时确定时。
boost::weak_ptr<T>
:
shared_ptr<T>
在可能发生指针循环的情况下使用 with 。
用法:用于在只有循环维护共享引用计数时停止循环保留对象。
c++ - 什么是智能指针,我应该什么时候使用它?
什么是智能指针,我应该什么时候使用它?
c++ - 提升 shared_ptr 容器问题
假设我有一个多线程应用程序使用的指针容器(std::vector)。在向容器添加新指针时,代码使用临界区 (boost::mutex) 进行保护。一切都很好。代码应该能够将这些指针之一返回给线程以进行处理,但另一个单独的线程可以选择删除这些指针之一,该指针可能仍在使用中。例如:
所以thread2可以在thread1使用它时删除指针。讨厌。
因此,我想使用 Boost 共享 ptrs 的容器。IIRC 这些指针将被引用计数,因此只要我返回共享 ptrs 而不是原始指针,从容器中删除一个不会真正释放它,直到最后一次使用它超出范围。IE
在上面的例子中,如果thread1在thread2调用erase之前获得了指针,那么指向的对象是否仍然有效?当thread1完成时它实际上不会被删除?请注意,对全局向量的访问将通过临界区进行。
我认为这就是 shared_ptrs 的工作方式,但我需要确定。
c++ - 指针和容器
我们都知道 RAW 指针需要包装在某种形式的智能指针中才能获得 Exception 安全的内存管理。但是当涉及到指针容器时,问题变得更加棘手。
std 容器坚持包含的对象是可复制的,因此这排除了 std::auto_ptr 的使用,尽管您仍然可以使用 boost::shared_ptr 等。
但也有一些 boost 容器明确设计用于安全地保存指针:
请参阅指针容器库
问题是:在什么情况下我应该更喜欢使用 ptr_containers 而不是 smart_pointers 容器?
c++ - boost::shared_ptr 标准容器
假设我有一个类 foo,并希望使用 std::map 来存储一些 boost::shared_ptrs,例如:
如果我向地图添加了一个新的 foo_sp 但使用的键已经存在,是否会删除现有条目?例如:
原来的指针(p)被p2替换后会被释放吗?我很确定它会是,但我认为值得询问/分享。
c++-cli - 托管 C++/CLI 类中的 auto_ptr 或 shared_ptr 等效项
在 C++/CLI 中,您可以在托管类中使用本机类型,但不允许在托管类中持有本机类的成员:在这种情况下您需要使用指针。
这是一个例子:
有人知道 C++/CLI 世界中的 shared_ptr 等价物吗?
编辑:感谢您的建议,“1800-信息”。根据您的建议,我检查了 STL.Net,但它仅适用于 Visual Studio 2008,它提供容器 + 算法,但没有智能指针。
c++ - 为什么不应该使用对智能指针的引用?
我记得在某处读过使用对智能指针的引用会导致内存损坏。这仅仅是因为在智能指针被销毁后使用了它的引用吗?还是引用计数搞砸了?
感谢您的澄清
c++ - 如何将协变返回类型与智能指针一起使用?
我有这样的代码:
此代码无法编译。
在视觉工作室它提出
C2555:覆盖虚函数返回类型不同且不是协变的
如果我不使用boost::shared_ptr
但返回原始指针,则代码编译(我理解这是由于 C++ 中的协变返回类型)。我可以看到问题是因为不是从boost::shared_ptr
of派生的。但是我想返回用于其他类,否则我必须在返回后转换返回值。 Ret1
boost::shared_ptr
RetInterface
boost::shared_ptr
Ret1
- 难道我做错了什么?
- 如果不是,为什么这种语言是这样的——在这种情况下处理智能指针之间的转换应该是可扩展的?是否有理想的解决方法?
c++ - 惯用 std::auto_ptr 还是只使用 shared_ptr?
现在shared_ptr
在 tr1 中,您认为使用 应该发生std::auto_ptr
什么?它们都有不同的用例,但auto_ptr
也可以用 解决所有用例shared_ptr
。auto_ptr
如果您想明确表示在任何给定点上只有一个类拥有所有权,您会放弃还是继续使用它?
我的看法是,使用auto_ptr
可以增加代码的清晰度,正是通过增加细微差别和代码设计的指示,但另一方面,它在培训新程序员时增加了另一个微妙的问题:他们需要理解智能指针和它们如何工作的详细信息。当您在任何地方只使用一个智能指针时,您只需制定一条规则“将所有指针包装在shared_ptr
”中并完成它。
你对此有何看法?