我开始研究C++ 11的智能指针,我没有看到任何有用的用法std::weak_ptr.有人能告诉我什么时候std::weak_ptr有用/必要吗?
我和其他许多人一样,使用智能指针在C++中包含不安全的内存操作,使用RAII等等,已经取得了巨大的成功.但是,当您具有析构函数,类,运算符重载等时,包装内存管理更容易实现.
对于使用原始C99编写的人,您可以在哪里指出(没有双关语)来帮助安全内存管理?
谢谢.
我一直在考虑使用共享指针,我知道如何自己实现它 - 不想这样做,所以我在尝试std::tr1::shared_ptr,我有几个问题......
引用计数是如何实现的?它是否使用双向链表?(顺便说一句,我已经用Google搜索了,但我找不到任何可靠的东西.)
使用它有任何陷阱std::tr1::shared_ptr吗?
如果我调用std::make_shared<T>(而不是仅仅shared_ptr<T>显式分配),那么出于性能原因,我希望引用计数在T的实例旁边分配.一切都很好.
但是如果我有weak_ptr引用相同对象的实例,可能他们需要访问该引用计数,以了解该对象是否仍然存在.
因此,当T的实例的最后一个shared_ptr被销毁时,对系统的天真理解意味着它不能释放存储T的内存,因为weak_ptrs仍然需要访问该计数.
似乎有一个单独的弱引用计数器,理论上它可以与T的实例分开保存,这样T可以被破坏,内存释放,而弱引用仍然存在.但后来我们又回到了两个单独的分配,挫败了它的好处make_shared.
我想我在这里误解了一些东西.std::make_shared当存在弱引用时,如何释放为构造的实例分配的内存?
我有一组Creature对象,使用std::make_shared和创建并拥有在我的应用程序的一部分中std::shared_ptr.
我还跟踪一个选择的零个或一个Creature在World使用对象std::weak_ptr<Creature>.
void World::SetSelection(const std::shared_ptr<Creature>& creature) {
selection = creature;
}
std::shared_ptr<Creature> World::GetSelection() const {
return selection.lock();
}
Run Code Online (Sandbox Code Playgroud)
调用者GetSelection负责检查指针是否为空.如果是,那意味着目前没有选择.
这一切都完全符合我的喜好:当选定Creature的自然原因(应用程序中的其他地方)死亡时,再次GetSelection开始返回nullptr,就像没有选择任何东西一样.
但是在这种情况下,World::selection成员仍然指向std::shared_ptr控制块.这可能非常大,因为我std::make_shared用来创建我的Creature对象(我意识到Creature对象在正确的时间被正确销毁但仍然分配了它的内存).我正在考虑GetSelection改为:
std::shared_ptr<Creature> World::GetSelection() {
const auto ret = selection.lock();
if (!ret)
selection.reset();
return ret;
}
Run Code Online (Sandbox Code Playgroud)
一旦我注意到它不再需要,它就会释放内存.令人讨厌的是,这个版本GetSelection不可能const.
GetSelection在这种情况下哪个版本被认为是最佳做法?
如果在模板化代码中发生类似的事情,那么答案是否会改变,哪些sizeof(T)是未知的并且可能是巨大的?或者在C++ 14中std::make_shared<T[]> …
下面的代码什么时候发生内存释放?
#include <memory>
int main()
{
auto p = std::make_shared<int>(5);
std::weak_ptr<int> wp = p;
p = nullptr;
return wp.lock() == nullptr ? 0 : 1;
}
Run Code Online (Sandbox Code Playgroud)
如下从这篇文章 std::make_shared执行一个堆分配。这是否意味着在至少有一个std::weak_ptr存活之前,内存不能被释放?
我正在使用std::atomics为参考计数器实现一个指针/弱指针机制(像这样).为了将弱指针转换为强指针,我需要原子化
有没有办法使用std::atomic_int?我认为必须使用其中之一compare_exchange,但我无法弄明白.