{"id":754,"date":"2020-01-22T16:30:11","date_gmt":"2020-01-23T00:30:11","guid":{"rendered":"http:\/\/209.126.2.187\/?p=754"},"modified":"2020-01-22T16:30:11","modified_gmt":"2020-01-23T00:30:11","slug":"custom-deleters-of-shared-unique-pointer","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2020\/01\/22\/custom-deleters-of-shared-unique-pointer\/","title":{"rendered":"Custom Deleters of Shared &#038; Unique Pointer"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In this post, I will introduce custom deleters when using C++ <code>std::shared_ptr<\/code> and <code>std::unique_ptr<\/code>. <\/p>\n<h2>Conclusion<\/h2>\n<p>Use the following snippets. Note the fourth case, where a <code>unique_ptr<\/code> with custom deleter will not pass the deleter to the <code>shared_ptr<\/code> when using <code>release()<\/code>.<\/p>\n<pre><code class=\"language-c++\">class OldThing {\n  public:\n    ~OldThing() \n    {\n      if (allocated_) {\n        std::cout &lt;&lt; &quot;MEMORY LEAK!&quot; &lt;&lt; std::endl;\n      }\n    }\n    void Deallocate()\n    {\n      std::cout &lt;&lt; &quot;Deallocate called.&quot; &lt;&lt; std::endl;\n      allocated_ = false;\n    }\n  private:\n    bool allocated_{ true };\n};\nint main() { \n  {\n    OldThing oldThing;\n    \/\/ oldThing going out of scope causes a &quot;memory leak&quot;\n  }\n\n  {\n    \/\/ shared_ptr&#039;s constuctor handles the deleter\n    std::shared_ptr&lt;OldThing&gt; p(new OldThing, \n      [] (OldThing* ot) {\n        ot-&gt;Deallocate();\n        delete ot;\n      }\n    );\n  }\n\n  {\n    \/\/ We need to include the deleter&#039;s type in the template parameters:\n    std::unique_ptr&lt;OldThing, void(*)(OldThing*)&gt; p(new OldThing, \n      [] (OldThing* ot) {\n         ot-&gt;Deallocate();\n         delete ot;\n      }\n    );\n  }\n\n  {\n    \/\/ !!! memory leak!!!\n    std::unique_ptr&lt;OldThing, void(*)(OldThing*)&gt; p(new OldThing, \n      [] (OldThing* ot) {\n         ot-&gt;Deallocate();\n         delete ot;\n      }\n    );\n    auto p_ = std::shared_ptr&lt;OldThing&gt;(p.release());\n  }\n\n  {\n    \/\/ works, shared_ptr receives the deleter from unique_ptr\n    std::unique_ptr&lt;OldThing, void(*)(OldThing*)&gt; p(new OldThing, \n      [] (OldThing* ot) {\n         ot-&gt;Deallocate();\n         delete ot;\n      }\n    );\n    std::shared_ptr&lt;OldThing&gt; p_ = std::move(p);\n  }\n\n  return 0;\n}<\/code><\/pre>\n<p>The result will be <\/p>\n<pre><code class=\"language-bash\">MEMORY LEAK!                                                                                                                                                                       \nDeallocate called.                                                                                                                                                                 \nDeallocate called.                                                                                                                                                                 \nMEMORY LEAK!                                                                                                                                                                       \nDeallocate called.   <\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, I will introduce custom deleters when using C++ std::shared_ptr and std::unique_ptr. Conclusion Use the following snippets. Note the fourth case, where a unique_ptr with custom deleter will not pass the deleter to the shared_ptr when using release(). class OldThing { public: ~OldThing() { if (allocated_) { std::cout &lt;&lt; &quot;MEMORY LEAK!&quot; &lt;&lt;&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-754","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/754","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=754"}],"version-history":[{"count":1,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/754\/revisions"}],"predecessor-version":[{"id":755,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/754\/revisions\/755"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}