Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How std::shared_ptr is deallocated?

Tags:

c++

c++17

When does memory deallocation occur in the code below?

#include <memory>

int main()
{
    auto p = std::make_shared<int>(5);
    
    std::weak_ptr<int> wp = p;
    
    p = nullptr;
    
    return wp.lock() == nullptr ? 0 : 1;
}

As follows from this post std::make_shared performs one heap-allocation. Does this mean that until at least one std::weak_ptr is alive the memory can't be deallocated?

like image 204
Dmitriano Avatar asked Nov 30 '20 21:11

Dmitriano


People also ask

What happens to a shared_ptr when it is deallocated?

As long as at least one std::shared_ptr is pointing to the resource, the resource will not be deallocated, even if individual std::shared_ptr are destroyed. As soon as the last std::shared_ptr managing the resource goes out of scope (or is reassigned to point at something else), the resource will be deallocated.

What is a shared_ptr in C++?

A shared_ptr can share ownership of an object while storing a pointer to another object. This feature can be used to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get (), the dereference and the comparison operators.

How does the destructor of shared_ptr work in C++?

The destructor of shared_ptr decrements the number of shared owners of the control block. If that counter reaches zero, the control block calls the destructor of the managed object. The control block does not deallocate itself until the std::weak_ptr counter reaches zero as well.

What happens when a shared_ptr is cloned?

However, when a std::shared_ptr is cloned using copy assignment, the data in the control block can be appropriately updated to indicate that there are now additional std::shared_ptr co-managing the resource. A std::unique_ptr can be converted into a std::shared_ptr via a special std::shared_ptr constructor that accepts a std::unique_ptr r-value.


2 Answers

(Had to edit the answer since I have not read the question properly).

Yes, the memory itself will be around in your snippet, since you have allocated a single block for both control block and the object via make_shared call.

like image 54
SergeyA Avatar answered Oct 12 '22 14:10

SergeyA


std::make_shared<T>() allocates a control block containing a constructed T instance, and then returns a std::shared_ptr that refers to that block. The T instance is destructed when no more std::shared_ptrs refer to the control block, but the control block itself is not freed until there are no more std::shared_ptrs or std::weak_ptrs referring to it. Which, in this example, is when both wp and p go out of scope when main() exits:

#include <memory>

int main()
{
    auto p = std::make_shared<int>(5);
    
    std::weak_ptr<int> wp = p;
    
    p = nullptr; // <-- the int is destroyed here
    
    return wp.lock() == nullptr ? 0 : 1;
} // <-- the control block is freed here when p and wp are destroyed
like image 29
Remy Lebeau Avatar answered Oct 12 '22 13:10

Remy Lebeau