Leaky lambdas and self referencing shared pointers

After a bit of a debugging session, I ended up looking at some code in a large project

The connection gets removed when the pointer inside m_foo gets de-allocated by the shared_ptr.
But the connection target is a lambda that has captured a copy of the shared_ptr…

There is at least a couple of solutions.

  • Keep the connection object (QMetaObject::Connection) around and call disconnect in your destructor. That way the connection gets removed and the lamda object should get removed
  • Capture the shared pointer by (const) reference. Capture the shared pointer as a weak pointer. Or as a raw pointer. All of this is safe because whenever the shared pointer gets a refcount of zero, the connection gets taken down with the object.

I guess the lesson learnt is be careful when capturing shared pointers.

Posted in english, kde, qt
2 comments on “Leaky lambdas and self referencing shared pointers
  1. Stefan says:

    As far as I know the concept of capturing a weak pointer instead of the shared pointer is sometimes names “weak_fn”.

    With Qt connections your other solutions sound “safe” apart from the one capturing the shared pointer by reference.

    I wrote a implementation for a “weak_fn” wrapper (which should be safe in any context): https://github.com/stbuehler/caney/blob/master/components/std/include/caney/std/weak_fn.hpp

  2. User says:

    May be you can write exactly how good solutions of
    * Capture the shared pointer by (const) reference.
    * Capture the shared pointer as a weak pointer.
    * Or as a raw pointer.
    will look like in the same context of your code example … because capturing noramlly is said to be by reference or by value. And you propose 3 more types of capturing. What is the best way to implement all these things in code?
    Thanks!