Boost C++ Libraries: Ticket #5: shared_ptr and self-owning objects https://svn.boost.org/trac10/ticket/5 <pre class="wiki">Consider following program: #include &lt;boost/smart_ptr.hpp&gt; #include &lt;iostream&gt; class foo { public: foo(): m_self(this) { std::cout &lt;&lt; "foo constructor\n"; } ~foo() { std::cout &lt;&lt; "foo destructor\n"; } void suicide() { m_self.reset(0); } private: boost::shared_ptr&lt;foo&gt; m_self; }; int main() { foo *foo_ptr = new foo; foo_ptr-&gt;suicide(); } When linked with Electric Fence this code fails. This code invokes undefined behavior in reset method of shared_ptr: when line if (--*pn == 0) { checked_delete(px); } executes shared_ptr object gets destroyed and line *pn = 1 acceses already freed memory. Why use m_self? foo's clients share foo by keeping shared_ptr to it. foo handles some asynchronous event which may render foo unneeded to itself (network connection close, for example), but it still may be needed to clients if any. OTOH, if no clients use foo at the time of the event then foo needs to destroy itself. This situation is best modeled with keeping shared_ptr in foo and letting foo to reset it when foo thinks it's mission is complete. The problem with shared_ptr can be solved with small modification to reset method: void reset(T* p=0) { T *old_px = px; if ( px == p ) return; // fix: self-assignment safe px = p; if (--*pn == 0) { *pn = 1; checked_delete(old_px); } else { // allocate new reference counter try { pn = new long(1); } // fix: prevent leak if new throws catch (...) { ++*pn; // undo effect of --*pn above to meet effects guarantee px = old_px; // undo effect of px = p above checked_delete(p); throw; } // catch } // allocate new reference counter } // reset operator=(const shared_ptr&amp;) and operator=(std::auto_ptr&amp;) have the same problem and fix is very similiar. </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5 Trac 1.4.3 darinadler Wed, 07 Nov 2001 17:42:55 GMT <link>https://svn.boost.org/trac10/ticket/5#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5#comment:1</guid> <description> <pre class="wiki">Logged In: YES user_id=243358 Peter Dimov is planning to fix this. </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Peter Dimov</dc:creator> <pubDate>Wed, 28 May 2003 12:02:55 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/5#comment:2 https://svn.boost.org/trac10/ticket/5#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> </ul> Ticket