Home > Enterprise >  why the raw pointer get by std::unique_ptr's get() can not delete the object and how is that im
why the raw pointer get by std::unique_ptr's get() can not delete the object and how is that im

Time:05-05

As the following code presents, I tried to delete the object by the raw pointer get from a unique_ptr. But, as the output shows, the complier reported errors. However, for raw pointers, we can do this int *p1 = new int{100}; int* p2 = p1; delete p2;.

Besides, I thought that unique_ptr maintain its ownership by move semantics. As the get() function of unique_ptr returns the raw pointer, how does the unique_ptr can still have the ownership of the object. Meanwhile, why the raw pointer doesn't get the ownership. At the same time, I am confusing how does this implemented. Thanks.

#include <iostream>
#include <memory>

int main(int argc, char const *argv[])
{
    std::unique_ptr<int> newPtr = std::make_unique<int>(1234);
    std::cout << *newPtr << std::endl;
    int* rawInt = newPtr.get();
    *rawInt = 200;
    delete rawInt;
    rawInt = nullptr;
    std::cout << *newPtr << std::endl; 
    return 0;
}

The code was performed on MacOs and the output is:

the output

CodePudding user response:

std::unique_ptr is a really simple class. Conceptually, it's basically just this:

template <typename T>
class unique_ptr
{
private:
    T* ptr;

public:
    unique_ptr(T* p) ptr{p} {}
    ~unique_ptr() { delete ptr; }

    T* get() { return ptr; }
    T* release() {
        T* p = ptr;
        ptr = nullptr;
        return p;
    }

    // other stuff
};

It just has a pointer member, and deletes the pointed-to object in its destructor. In reality there's a bit more to it, but that's essentially it.

The get member just returns a copy of the unique_ptr's managed pointer. That's it. Since the unique_ptr's pointer member is still pointing to that object, its destructor will still delete the object. If you also delete that object via another pointer to it then it will get deleted twice, which results in undefined behavior.

The release member function, on the other hand, sets the unique_ptr's pointer member to nullptr before returning a copy of its original value. Since its member pointer is null, its destructor won't delete anything.

  • Related