#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
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 delete
d 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.