为什么unique_ptr :: release()不释放分配的内存?

时间:2018-07-12 09:38:19

标签: c++

我被告知:

u = nullptr    删除unique_ptr u指向的对象;使u为空

u.release()    放弃对指针u的控制;返回指针u的控制,并使u为空;

AFAIK,unique_ptr::release()不应释放分配的内存,因为它是为转移所有权而发明的。

因此,我一直认为上面u中提到的“使u.release()为空”与u = nullptr不同。也许u本身不是null,只有get.()返回nullptr,如cpprefence中所述。

但是我得到了

#include <memory> 
#include <iostream> 
using namespace std;
int main()
{
    unique_ptr<string> p1(new string("Thank you guys"));
    string* p2 = p1.release();
    cout << std::boolalpha << (p1 == nullptr); //true
}

那么在release()p1 == nullptr之后,为什么在这种情况下不能释放分配的动态内存?我想念什么?


enter image description here

2 个答案:

答案 0 :(得分:4)

  

为什么在这种情况下不能释放分配的动态内存?   我想念什么?

因为您已将其所有权转移到p2

现在您有了一个拥有的原始指针,可以通过delete或将所有权转移到其他地方来清理原始指针。

您讨论的每个操作都有 distinct子句。使u为空是 not u = nullptr

的总数

u = nullptr

  1. 删除u指向的对象
  2. 使u为空

u.release()

  1. 放弃对u指向的对象的控制
  2. 使u为空

如果将“使u为空”定义为等效于u = nullptr,则将具有循环定义。相反,它意味着在操作之后,u == nullptrtrue

您可以自己实现unique_ptr。这是一个(精简版)版本,展示了差异

template<typename T>
class unique_ptr
{
    T* ptr;
public:
    explicit unique_ptr(T* arg = nullptr) : ptr(arg) {}
    ~unique_ptr() { delete ptr; }

    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;

    unique_ptr& operator=(std::nullptr_t) { delete ptr; ptr = nullptr; }
    T* release() { T* temp = ptr; ptr = nullptr; return temp; }

    friend bool operator==(const unique_ptr& lhs, const T* rhs) { return lhs.ptr == rhs; }
    friend bool operator==(const T* lhs, const unique_ptr& rhs) { return lhs == rhs.ptr; }
}

该分配删除存在的所有内容,然后分配传递的参数。 release复制成员,将其设置为nullptr,然后返回副本。

答案 1 :(得分:1)

因为要释放指针的控制权,而不是删除它。例如,如果您想将unique_ptr转换为shared_ptr,该怎么办。您可能会这样:

shared_ptr<string> upgrade(p1.release());

您要从唯一指针的控制中释放指针,并设置一个可以控制它的共享指针。另一个示例可能是您是否希望将此指针传递给c库。

在示例u = nullptr中,您没有释放指针。没有人可以恢复u的指向地址,因此必须将其删除。这是operator=重载的一部分。


*实际上应如何将unique_ptr转换为shared_ptr

std::shared_ptr<std::string> shared = std::move(unique);