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

why does this `std::shared_ptr<>`managed object leak?


#include <iostream>
#include <memory>
#include <vector>

using namespace std;

class test : public enable_shared_from_this<test> {
    vector<shared_ptr<test>> vec;
public:

    void addvec()
    {
        vec.emplace_back(shared_from_this());
    }
    ~test() { cout << "destructing\n"; }
};


int main()
{
    auto sp = make_shared<test>();

    sp->addvec(); // when called, destructor is not invoked and
                  // LeakSanitizer reports a memory leak
}

A test object is managed by std::shared_ptr and, after calling addvec, a second shared_ptr instance is stored in the internal vector (ref_count == 2).

But the destructor is never called and a memory leak is reported. Why is this?

Compiled with g++ -g -fsanitize=leak c.cpp
GCC version 12.2.1


Solution

  • The shown code results in a circular reference. The object ends up containing a shared_ptr to itself.

    A shared_ptr-referenced object gets automatically deleted only when the last shared_ptr to that object, itself, gets destroyed.

    This never happens, in the shown code. Hence, the memory leak.

    So-called "smart" pointers only work as long as there are no circular references, by definition.

    With some careful planning, the services of a std::weak_ptr can be employed in order to deal with this situation.