1

I'm aware that using smart pointers like std::shared_ptr adds garbage collection when the pointer goes out of scope, but I'm unclear as to whether the garbage collection also works if I call make_shared()multiple times on one shared_ptr.

For example:

std::shared_ptr<MyClass> mcPtr;

void assignment(int i)
{
  mcPtr = std::make_shared<MyClass>(i);
}

void main()
{
  assignment(5);

  // Some time later

  assignment(10);  // Does this cause a memory leak?
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Sonic Atom
  • 436
  • 5
  • 15
  • 1
    _"... but I'm unclear as to whether the garbage collection also works ..."_ Yes, it will delete the old value, and replace with the new one. Also note _garbage collection_ is somewhat different than using smart pointers. – πάντα ῥεῖ Sep 15 '15 at 14:45
  • Presented code doesn't exhibit memory leak. – Jarod42 Sep 15 '15 at 14:58
  • Only way to leak memory with `shared_ptr` (assuming using it properly, without ugly hacks) is to create circular dependency. Reassigning to it definitely would be handled properly. – Slava Sep 15 '15 at 15:15

1 Answers1

2

using a std::shared_ptr doesn't add garbage collection but when the shared pointer is destroyed at the end of the scope it is declared in it's destructor will be called. The destructor of the shared pointer handles releasing the memory.

Now when you call = std::shared_ptr::operator=() is called. From the standard 20.8.2.2.3.4

Effect: Equivalent to shared_ptr(std::move(r)).swap(*this)

So mcPtr is given the value of the new shared_ptr and the new shared_ptr gets the contents of mcPtr. Then the new shared_ptr goes out of scope, the destructor is called and the shared_ptr takes care of itself.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • That's a great explanation, thanks! Am I right in assuming the new shared_ptr will go out of scope immediately because it's an rvalue? Or does it wait until the end of the function? Or to put it another way, would this cause a problem (assuming the optimiser didn't remove it)... `for(;;) { mcPtr = make_shared(); }` – Sonic Atom Sep 15 '15 at 15:14
  • 1
    Temporary objects are destroyed at the end of the full expression they're part of. for more reading: [C++: Life span of temporary arguments?](http://stackoverflow.com/questions/2506793/c-life-span-of-temporary-arguments) – NathanOliver Sep 15 '15 at 15:15
  • Just as an aside, how does this actually work behind the scenes? The obvious question would be _"but what calls the shared pointer's destructor?"_ Obviously the compiler reclaims memory on the stack (and other temporary location like registers) when those objects go out of scope, but does it have the sense to call the destructors of those objects too? Is that how smart pointers work? – Sonic Atom Sep 16 '15 at 12:30
  • @SonicAtom Yes. When an objects lifetime ends, which is end of scope for named objects or end of expression for temporary objects, the destructor of the object is called. This is what makes value semantics so attractive as it is like have instant automatic garbage collection – NathanOliver Sep 16 '15 at 12:35