微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当 unique_ptr 设置为 nullptr 时,谁以及何时删除对象

如何解决当 unique_ptr 设置为 nullptr 时,谁以及何时删除对象

我使用了一个带有 unique_ptr 指向对象的类,方法在运行时将它异步设置为 nullptr,然后另一个方法可能会调用 make_unique 并将提到的指针设置为这个新对象。

void Class0::f0()
{
    mPtr = std::make_unique<Class1>();
}

void Class0::f1(SomeType param)
{
    mPtr->doWork(param);
    mPtr      = nullptr; 
}

//f1 called after f0 asynchronIoUsly,any number of times

谁以及何时删除了未明确删除的前一个? unique_ptr 仍然存在,因为它是一个类字段,所以它的析构函数永远不会被调用,但是 unique_ptr 可以设置为 nullptr 并且 make_unique 可以被多次调用。 我几乎可以肯定它会导致内存泄漏,并且必须首先显式调用 mPtr.reset()。 但是我在visual studio c++中做了一个小测试,没有泄漏。

void f()
{
    std::unique_ptr<std::vector<std::vector<int>>> ptr = std::make_unique<std::vector<std::vector<int>>>(100000);
    ptr = nullptr;
    f();
}

递归只检查内存使用情况,有和没有 ptr = nullptr; 我已经尝试过使用 -O0 的 WSL g++,结果完全相同。有人可以解释一下吗?

解决方法

谁以及何时删除了未明确删除的前一个?

不显式删除智能指针管理的对象是首先使用智能指针的原因。要正确管理对象的生命周期,需要的不仅仅是删除 unique_ptr 的析构函数中的对象(请参阅 What is The Rule of Three?)。除非你做了一些奇怪的事情,否则假设智能指针正确管理生命周期是相当安全的。

这里的 ptr = nullptr; 是来自 cppreference/unique_ptr/operator= 的重载 (3):

unique_ptr& operator=( std::nullptr_t ) noexcept;     (3)     

实际上与调用 reset() 相同。

还有reset()

void reset( pointer ptr = pointer() ) noexcept;

替换托管对象。

给定由 *this 管理的指针 current_ptr,按顺序执行以下操作:

  • 保存当前指针的副本 old_ptr = current_ptr
  • 用参数 current_ptr = ptr 覆盖当前指针
  • 如果旧指针不为空,则删除之前管理的对象
    if(old_ptr) get_deleter()(old_ptr)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。