Search code examples
c++c++11moveunique-ptr

Who is responsible for deletion of heap allocated object when moving it?


What happens when class is created with new, and then move constructor of the class is executed? Is the original creator still responsible for deletion? Example below runs fine (http://ideone.com/rS2LR9), but shouldn't it crash in second scope since owner goes out of scope before vector and hence deletes the object?

I am obviously misunderstanding something here, what happens to the ownership after std::move?

#include <iostream>
#include <memory>
#include <vector>
#include <utility>

class Owner {
public:
Owner() : data_(new int(1)) {}
int& get() {return *data_;}
private:
std::unique_ptr<int> data_;

Owner(const Owner&) = delete;
void operator=(const Owner&) = delete;
};

int main()
{
    {
        Owner owner;
        std::vector<int> test;
        test.emplace_back(std::move(owner.get()));
        std::cout << test[0] << std::endl;
    }

    {
        std::vector<int> test;
        {
                Owner owner;
                test.emplace_back(std::move(owner.get()));
        }
        std::cout << test[0] << std::endl;
    }

    {
        Owner owner;

        {
            std::vector<int> test;
            test.emplace_back(std::move(owner.get()));
            std::cout << test[0] << std::endl;
        }
    }
}

Solution

  • You're not moving any data here. When you call Owner::get(), you're exposing a reference to int, and when you call std::move() on that reference, you're making a trivial cast. There's nothing for std::vector::emplace_back() to "steal" away from Owner, because int has no move constructor.

    I'm guessing that you think that the std::unique_ptr inside Owner plays into these operations, but it doesn't; you're dereferencing that pointer, but never attempting to move its content. To do so, you'd have to invoke std::unique_ptr's move constructor or assignment operator.