Signals Memory

Started by RGPaul, 20 April 2023, 13:47:23

RGPaul

Hey texus,

I'm wondering if you need to disconnect a signal in order to don't leak memory?
If I create a Signal using a lambda. Will it be freed at any time?

Regards

texus

In general, the rule is that you don't have to do anything. The signal and lambda function are automatically freed when the widget on which you are connecting is destroyed.

However, it is very easy to accidentally introduce a memory leak when capturing widgets in the lambda. When capturing a shared_ptr in the lambda by value (and Widget::Ptr objects are shared_ptr objects), the captured object won't be destroyed until the lambda itself is destroyed. So if the captured widget is the widget that owns the signal, or the parent of the widget, then there is circular dependency between the widgets and signals, so nothing will be destroyed and the widget leaks.

If you disconnect the signal manually, the circular dependency would be broken. Another method to prevent this issue is to simply never capture a shared_ptr by value, instead capture the raw pointer:
Code (cpp) Select
button->onPress([panel]{ /* panel->... */ }); // Memory leak if button is part of panel
button->onPress([p = panel.get()]{ /* p->... */ }); // No leaks

RGPaul

Thank you for this great answer. That helped me alot to understand the behaviour.  :D