vendredi 13 septembre 2019

Why 'std::make_shared' is always using the global memory allocation even with class overloaded new/delete operators?

When using std::make_shared<C> the class overloaded new/delete operators are not called.

When using std::shared_ptr<C>, std::unique_ptr<C> & std::make_unique<C> the class overloaded new/delete operators are used.

When looking at the documentation that’s perfectly correct and well documented.

cppreference perfectly explains the behavior:

std::make_shared uses ::new, so if any special behavior has been set up using a class-specific operator new, it will differ from std::shared_ptr(new T(args...)).

Below is some pseudo-code to better highlight the behavior:

#include <memory>

class C
{
public:
    void * operator new(size_t size)
    { 
        void * p = ::operator new(size); 
        std::cout << "C::new() -> " << p << "\n";
        return p;
    }

    void operator delete(void * p)
    {
        std::cout << "C::delete() -> " << p << "\n";
        ::operator delete(p);
    }
};

std::shared_ptr<C> ptr = std::make_shared<C>();

At the external point of view, it seems inconsistent and error prone. Overloading class new/delete operators should always be used.

So, what is the rational of the behavior?

And, where is the C++ specification detailing the std::make_shared behavior?

Thanks for your help.

Aucun commentaire:

Enregistrer un commentaire