{"id":446,"date":"2016-07-14T21:27:59","date_gmt":"2016-07-14T20:27:59","guid":{"rendered":"http:\/\/pusling.com\/blog\/?p=446"},"modified":"2016-07-14T21:27:59","modified_gmt":"2016-07-14T20:27:59","slug":"leaky-lambdas-and-self-referencing-shared-pointers","status":"publish","type":"post","link":"https:\/\/pusling.com\/blog\/?p=446","title":{"rendered":"Leaky lambdas and self referencing shared pointers"},"content":{"rendered":"<p>After a bit of a debugging session, I ended up looking at some code in a large project<\/p>\n<pre class=\"lang:c++ decode:true \" >m_foo = std::make_shared&lt;SomeQObject&gt;();\r\n\/* plenty of lines and function boundaries left out *\/ \r\n(void)connect(m_foo.get(), &amp;SomeQObject::someSignal, [m_foo]() {\r\n  \/* *\/\r\n});<\/pre>\n<p>The connection gets removed when the pointer inside m_foo gets de-allocated by the shared_ptr.<br \/>\nBut the connection target is a lambda that has captured a copy of the shared_ptr&#8230;<\/p>\n<p>There is at least a couple of solutions. <\/p>\n<ul>\n<li>\nKeep 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\n<\/li>\n<li>\nCapture 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.\n<\/li>\n<\/ul>\n<p>I guess the lesson learnt is be careful when capturing shared pointers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After a bit of a debugging session, I ended up looking at some code in a large project m_foo = std::make_shared&lt;SomeQObject&gt;(); \/* plenty of lines and function boundaries left out *\/ (void)connect(m_foo.get(), &amp;SomeQObject::someSignal, [m_foo]() { \/* *\/ }); The connection gets removed when the pointer inside m_foo gets de-allocated by the shared_ptr. But the connection [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4,11],"tags":[],"class_list":["post-446","post","type-post","status-publish","format-standard","hentry","category-english","category-kde","category-qt"],"_links":{"self":[{"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=446"}],"version-history":[{"count":1,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/446\/revisions"}],"predecessor-version":[{"id":447,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/446\/revisions\/447"}],"wp:attachment":[{"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pusling.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}