Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must shared_ptr<> allocate for the control block and managed object separately?

This linked question asked if the make_shared<> function and the shared_ptr<> constructor differ.

What happens when using make_shared

Part of the answer was that make_shared<> will usually allocate memory for both the pointed to object and smart pointer control block in a single allocation. The shared_ptr<> constructors use two allocations.

cppreference states that the constructors "must" do so but no reason is given.

Why is this? Is it for some reason impossible? Or is it forbidden by the standard for some other reason?

like image 619
Praxeolitic Avatar asked Oct 14 '14 02:10

Praxeolitic


People also ask

What is the purpose of the shared_ptr <> template?

std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.

Why would you choose shared_ptr instead of unique_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.

What is control block in shared_ptr?

A control block is created when a std::shared_ptr is constructed from a unique-ownership pointer (i.e., a std::unique_ptr or std::auto_ptr ). Unique-ownership pointers don't use control blocks, so there should be no control block for the pointed-to object.

In what situation is a shared_ptr more appropriate than a unique_ptr?

Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.


1 Answers

Think about how the std::shared_ptr constructor works:

std::shared_ptr<Foo>(new Foo());

First the new Foo() expression is evaluated; ::operator new allocates memory for the Foo object and then constructs it. The resulting pointer is passed in as an argument to the std::shared_ptr constructor.

See the problem? The Foo allocation has already been performed! The smart pointer constructor has no option to allocate room for both the control block and the object in the same allocation, since it was not responsible for allocating memory for the object.

std::make_shared, on the other hand, is in charge of both allocations and so it is possible to allocate room for both in one heap allocation, and then placement-new-construct both the object and control block within that one allocation.

like image 162
cdhowie Avatar answered Oct 16 '22 16:10

cdhowie