A possible make_shared bug

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

A possible make_shared bug

chengm204
Hi GCC developers:

Assume I have a class:

Class FOO
{
Public:
    void* operator new(size_t size);
    void* operator new(size_t size, const std::nothrow_t &) noexcept;
    void  operator delete(void *doomed,size_t size);
    void* operator new [](size_t size);
    void  operator delete [](void* object);
    static void NewMemPool();
    static void DeleteMemPool();
}

These operator new/delete will get a buffer from a mempool created by NewMemPool and return a buffer to the pool.
Now if I have stmt without first call NewMemPool() :

std::shared_ptr<FOO> p(new FOO());

the program will crash.

However if I just call this directly

auto& p = std::make_shared<FOO>();  // I did not call NewMemPool yet.
My program is happy.

Should std::make_shared call my class operator new also? What’s the concept behind std::make_shared?

Warm Regards.
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10

Reply | Threaded
Open this post in threaded view
|

Re: A possible make_shared bug

Jonathan Wakely-4
On Wed, 9 Oct 2019 at 08:09, Ming Cheng wrote:
>
> Hi GCC developers:

This is the wrong mailing list for your question. It would be
appropriate on the gcc-help or libstdc++ lists. Please see
https://gcc.gnu.org/lists.html and take any further discussion to one
of those lists.

> Assume I have a class:
>
> Class FOO
> {
> Public:
>     void* operator new(size_t size);
>     void* operator new(size_t size, const std::nothrow_t &) noexcept;
>     void  operator delete(void *doomed,size_t size);
>     void* operator new [](size_t size);
>     void  operator delete [](void* object);
>     static void NewMemPool();
>     static void DeleteMemPool();
> }
>
> These operator new/delete will get a buffer from a mempool created by NewMemPool and return a buffer to the pool.
> Now if I have stmt without first call NewMemPool() :
>
> std::shared_ptr<FOO> p(new FOO());
>
> the program will crash.
>
> However if I just call this directly
>
> auto& p = std::make_shared<FOO>();  // I did not call NewMemPool yet.
> My program is happy.
>
> Should std::make_shared call my class operator new also? What’s the concept behind std::make_shared?

It's unspecified whether make_shared<FOO> does 'new FOO' or not, and
in practice only low quality implementations would do that.

What most implementations do is reserve additional space in the
shared_ptr control block and use placement new to construct the object
in that control block. That means there is only one allocation,
instead of one for 'new FOO' and one to allocate the control block.