Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour for unique_pointer in Visual Studio 2010

I tried writing this class

#include <memory>

class ContainerUnique
{
public:

    ContainerUnique(void);
    ~ContainerUnique(void);

private:
    std::unique_ptr<UniqueElement> u;
};

Where UniqueElement is a POD class defined elsewhere. I now define the constructor body like this:

ContainerUnique::ContainerUnique(void)
{
    auto tmp = new UniqueElement(1);

    this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile?
}

And it complies without exceptions. Running the program I find that after the constructor of ContainerUnique has been called, u contains a null pointer.

Is this the intended behaviour? And what unique_ptr method am I actually calling?

like image 247
Coffee on Mars Avatar asked Jul 02 '12 14:07

Coffee on Mars


People also ask

What happens when unique_ptr goes out of scope?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

What happens when you move a unique_ptr?

A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it.

Can unique_ptr be assigned?

It can be assigned: class owner { std::unique_ptr<someObject> owned; public: owner() { owned=std::unique_ptr<someObject>(new someObject()); } };


2 Answers

This is a known problem with VS2010's unique_ptr. It publicly inherits from its deleter if it's empty as an optimization (empty base optimization). The downside to the public inheritance is that all members of the deleter also become available members of unique_ptr, in this case its operator()(T*) that deletes the pointer.

The bug is fixed in VS2012's library where the inheritance is changed to private.

like image 157
Xeo Avatar answered Sep 23 '22 06:09

Xeo


You are calling default_delete< UniqueElement >::operator () ( UniqueElement* ptr ), because uniqe_ptr derives from it (to benefit from empty base class optimization), and it deletes ptr. It's not exactly intended behavior for you, although I don't think the standard forbids it.

like image 34
stijn Avatar answered Sep 26 '22 06:09

stijn