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

Who and when deletes object when unique_ptr was set to nullptr

我使用 class 和 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 仍然存在,因为它是一个 class 字段,所以它的析构函数永远不会被调用,但是 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++,结果完全相同。有人可以解释一下吗?

Who and when deletes this previous that was not explicitly deleted?

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

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

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

Effectively the same as calling reset().

reset()

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

Replaces the managed object.

Given current_ptr, the pointer that was managed by *this, performs the following actions, in this order:

  • Saves a copy of the current pointer old_ptr = current_ptr
  • Overwrites the current pointer with the argument current_ptr = ptr
  • If the old pointer was non-empty, deletes the previously managed object
    if(old_ptr) get_deleter()(old_ptr).