Search code examples
c++c++11shared-ptr

Why does the shared pointer does not delete memory?


shared_ptr<string> pNico(new string("Nico"));
shared_ptr<string> pJutta(new string("Jutta"));
// put them multiple times in a container
vector<shared_ptr<string>> whoMadeCoffee;
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);

pNico = nullptr;         
whoMadeCoffee.resize(2);

At the end of the program, when the last owner of the string gets destroyed, the shared pointer calls delete for the object it refers to. Such a deletion does not necessarily have to happen at the end of the scope. For example, assigning the nullptr to pNico or resizing the vector so that it contains only the first two element s would delete the last owner of the string initialized with nico .

(from Josuttis, Nicolai M.. "The C++ Standard Library.")

My question is why in above mention case it is not guaranteed that memory of "Nico" object will be deleted at the end of the scope?

Although if we do this instead

whoMadeCoffee.resize(2);
pNico = nullptr;

The memory associated with "Nico" does get deleted.

Can someone please explain the difference?


Solution

  • At the end of the program, when the last owner of the string gets destroyed, the shared pointer calls delete for the object it refers to. Such a deletion does not necessarily have to happen at the end of the scope.

    string("Nico") will be destroyed when the reference count reaches 0. In your example it reaches to 0 (for Nico) even before reaching the end of scope.

    It can live out of its scope if you share with somebody else out of your current scope for example having a function that returns a shared_ptr or here is an even simpler example:

    shared_ptr<string> pNico0(new string(""));
    { 
        shared_ptr<string> pNico1(new string("Nico"));
        pNico0 = pNico1; // pNico0 reference count = 2
    }
    // pNico0 reference count = 1
    

    Live on godbolt