Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Cyclic references: a <code>shared_ptr&lt;&gt;</code> to something that has a <code>shared_ptr&lt;&gt;</code> to the original object. You can use <code>weak_ptr&lt;&gt;</code> to break this cycle, of course.</p> <hr> <p>I add the following as an example of what I am talking about in the comments.</p> <pre><code>class node : public enable_shared_from_this&lt;node&gt; { public : void set_parent(shared_ptr&lt;node&gt; parent) { parent_ = parent; } void add_child(shared_ptr&lt;node&gt; child) { children_.push_back(child); child-&gt;set_parent(shared_from_this()); } void frob() { do_frob(); if (parent_) parent_-&gt;frob(); } private : void do_frob(); shared_ptr&lt;node&gt; parent_; vector&lt; shared_ptr&lt;node&gt; &gt; children_; }; </code></pre> <p>In this example, you have a tree of nodes, each of which holds a pointer to its parent. The frob() member function, for whatever reason, ripples upwards through the tree. (This is not entirely outlandish; some GUI frameworks work this way).</p> <p>The problem is that, if you lose reference to the topmost node, then the topmost node still holds strong references to its children, and all its children also hold a strong reference to their parents. This means that there are circular references keeping all the instances from cleaning themselves up, while there is no way of actually reaching the tree from the code, this memory leaks.</p> <pre><code>class node : public enable_shared_from_this&lt;node&gt; { public : void set_parent(shared_ptr&lt;node&gt; parent) { parent_ = parent; } void add_child(shared_ptr&lt;node&gt; child) { children_.push_back(child); child-&gt;set_parent(shared_from_this()); } void frob() { do_frob(); shared_ptr&lt;node&gt; parent = parent_.lock(); // Note: parent_.lock() if (parent) parent-&gt;frob(); } private : void do_frob(); weak_ptr&lt;node&gt; parent_; // Note: now a weak_ptr&lt;&gt; vector&lt; shared_ptr&lt;node&gt; &gt; children_; }; </code></pre> <p>Here, the parent node has been replaced by a weak pointer. It no longer has a say in the lifetime of the node to which it refers. Thus, if the topmost node goes out of scope as in the previous example, then while it holds strong references to its children, its children don't hold strong references to their parents. Thus there are no strong references to the object, and it cleans itself up. In turn, this causes the children to lose their one strong reference, which causes them to clean up, and so on. In short, this wont leak. And just by strategically replacing a shared_ptr&lt;> with a weak_ptr&lt;>.</p> <p>Note: The above applies equally to std::shared_ptr&lt;> and std::weak_ptr&lt;> as it does to boost::shared_ptr&lt;> and boost::weak_ptr&lt;>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload