{"id":2141,"date":"2014-02-19T13:00:01","date_gmt":"2014-02-19T13:00:01","guid":{"rendered":"http:\/\/writeasync.net\/?p=2141"},"modified":"2014-02-18T08:12:16","modified_gmt":"2014-02-18T08:12:16","slug":"avoiding-memory-leaks-part-2","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=2141","title":{"rendered":"Avoiding memory leaks: part 2"},"content":{"rendered":"<p>In the <a href=\"http:\/\/writeasync.net\/?p=2051\">previous post<\/a> I introduced some of the common cases for avoiding memory leaks with judicious use of <code>unique_ptr<\/code>. Of course, not all memory management situations are as straightforward, especially when dealing with low-level &#8220;C-style&#8221; APIs. Let&#8217;s explore a few more examples.<\/p>\n<h2>Release ownership to legacy API<\/h2>\n<p>To release ownership of an object to code that doesn&#8217;t understand <code>unique_ptr<\/code>, you can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee475597.aspx\"><code>release<\/code><\/a> method. This ensures that at least your usage of the object is exception-safe up to the point you relinquish it.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid LegacyCodeToTakeResponsibility(MyClass * p)\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    wcout &lt;&lt; L&quot;I take responsibility for &quot; &lt;&lt; p-&gt;get_Name() &lt;&lt; endl;\r\n    \/\/ ... sometime later ...\r\n    delete p;\r\n}\r\n\r\nvoid ReleaseOwnership()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    MyClassUPtr p = make_unique&lt;MyClass&gt;(L&quot;to-be-released&quot;);\r\n    \/\/ ... do some work here that might cause an exception ...\r\n\r\n    \/\/ Okay, now it's safe to give this away.\r\n    LegacyCodeToTakeResponsibility(p.release());\r\n    if (!p)\r\n    {\r\n        wcout &lt;&lt; L&quot;I can't use this instance anymore.&quot; &lt;&lt; endl;\r\n    }\r\n}\r\n\r\nint wmain(int argc, wchar_t ** argv)\r\n{\r\n    ReleaseOwnership();\r\n    wcout &lt;&lt; L&quot;Final count: &quot; &lt;&lt; Counter::N &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>The output shows that the object is only released once and that the <code>unique_ptr<\/code> no longer refers to any valid instance:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{ Enter ReleaseOwnership\r\n(Dynamic allocation)\r\nMyClass:to-be-released\r\n{ Enter LegacyCodeToTakeResponsibility\r\nI take responsibility for to-be-released\r\n~MyClass:to-be-released\r\n(Dynamic deallocation)\r\n} Leave LegacyCodeToTakeResponsibility\r\nI can't use this instance anymore.\r\n} Leave ReleaseOwnership\r\nFinal count: 0\r\n<\/pre>\n<h2>Use custom deleter<\/h2>\n<p>Not all objects can be freed using <code>delete<\/code>. This is particularly true of resources that you did not explicitly allocate. In this example, a custom deleter is defined (as a template class which overloads the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/df74sak1.aspx\">function call operator<\/a>) which can free a buffer allocated by <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms679351(v=vs.85).aspx\">FormatMessage<\/a> using <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa366730(v=vs.85).aspx\"><code>LocalFree<\/code><\/a> as documented by the API:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;Windows.h&gt;\r\n\/\/ ...\r\n\r\ntemplate &lt;typename T&gt;\r\nstruct LocalFreeDelete\r\n{\r\n    void operator()(T * ptr) const\r\n    {\r\n        wcout &lt;&lt; L&quot;LocalFree&quot; &lt;&lt; endl;\r\n        LocalFree(ptr);\r\n        --Counter::N;\r\n    }\r\n};\r\n\r\nvoid FormatSomeMessage()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    wchar_t const * message = L&quot;Name: %1 \/ City: %2&quot;;\r\n    wchar_t const * name = L&quot;Xyz&quot;;\r\n    wchar_t const * city = L&quot;Abc&quot;;\r\n\r\n    DWORD_PTR args&#x5B;] = { (DWORD_PTR)name, (DWORD_PTR)city };\r\n\r\n    LPWSTR rawBuffer = nullptr;\r\n    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY;\r\n    DWORD result = FormatMessage(flags, message, 0, 0, (LPWSTR)&amp;rawBuffer, 64, (va_list *)args);\r\n    if (result != 0)\r\n    {\r\n        \/\/ Immediately wrap buffer to ensure it is safely freed\r\n        unique_ptr&lt;WCHAR, LocalFreeDelete&lt;WCHAR&gt;&gt; p(rawBuffer);\r\n        ++Counter::N;\r\n        wcout &lt;&lt; L&quot;Formatted string: &quot; &lt;&lt; p.get() &lt;&lt; endl;\r\n        \/\/ ... now do something with the buffer ...\r\n    }\r\n}\r\n\r\nint wmain(int argc, wchar_t ** argv)\r\n{\r\n    FormatSomeMessage();\r\n    wcout &lt;&lt; L&quot;Final count: &quot; &lt;&lt; Counter::N &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>The output shows that we have indeed freed the buffer on exit of the scope:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{ Enter FormatSomeMessage\r\nFormatted string: Name: Xyz \/ City: Abc\r\nLocalFree\r\n} Leave FormatSomeMessage\r\nFinal count: 0\r\n<\/pre>\n<h2>Multiple owner ref-counting<\/h2>\n<p>Alas, not every object is uniquely owned. Just as <a href=\"http:\/\/www.quotationspage.com\/quote\/36970.html\">success has a thousand fathers<\/a>, some objects have more than one logical parent. To avoid orphaning the memory, <a href=\"\"><code>shared_ptr<\/code><\/a> is the tool for this situation. It internally maintains a reference count to ensure that the final instance that goes out of scope will destroy the object. Here is an example which uses the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd492418.aspx\">PPL<\/a>:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;Windows.h&gt;\r\n#include &lt;sstream&gt;\r\n#include &lt;vector&gt;\r\n#include &lt;ppltasks.h&gt;\r\n#include &lt;concurrent_queue.h&gt;\r\n\r\nusing namespace std;\r\nusing namespace concurrency;\r\n\r\n\/\/ ...\r\nvoid StartParallelTasks(vector&lt;task&lt;void&gt;&gt; &amp; tasks, concurrent_queue&lt;wstring&gt; &amp; queue)\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    MyClassSPtr sp = make_shared&lt;MyClass&gt;(L&quot;shared-obj&quot;);\r\n    for (int i = 0; i &lt; 5; ++i)\r\n    {\r\n        task&lt;void&gt; task = create_task(&#x5B;sp, &amp;queue]()\r\n        {\r\n            Sleep(500);\r\n            DWORD id = GetCurrentThreadId();\r\n            wstringstream wss;\r\n            wss &lt;&lt; L&quot;T:&quot; &lt;&lt; id &lt;&lt; L&quot;:&quot; &lt;&lt; sp-&gt;get_Name();\r\n            queue.push(wss.str());\r\n        });\r\n        tasks.push_back(task);\r\n    }\r\n}\r\n\r\nvoid StartAndWaitForTasks()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    vector&lt;task&lt;void&gt;&gt; tasks;\r\n    concurrent_queue&lt;wstring&gt; queue;\r\n    StartParallelTasks(tasks, queue);\r\n\r\n    task&lt;void&gt; allTasksCompleted = when_all(tasks.begin(), tasks.end()).then(&#x5B;&amp;queue]()\r\n    {\r\n        for_each(queue.unsafe_begin(), queue.unsafe_end(), &#x5B;](wstring &amp; s)\r\n        {\r\n            wcout &lt;&lt; s &lt;&lt; endl;\r\n        });\r\n    });\r\n\r\n    allTasksCompleted.wait();\r\n}\r\n\r\nint wmain(int argc, wchar_t ** argv)\r\n{\r\n    StartAndWaitForTasks();\r\n    wcout &lt;&lt; L&quot;Final count: &quot; &lt;&lt; Counter::N &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>The output shows that even though the initial <code>shared_ptr<\/code> instance is long gone, the copies which were passed to the task lambda (via the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd293603.aspx\">capture clause<\/a>) keep the object alive until the last task finishes:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{ Enter StartAndWaitForTasks\r\n{ Enter StartParallelTasks\r\nMyClass:shared-obj\r\n} Leave StartParallelTasks\r\nT:27200:shared-obj\r\n~MyClass:shared-obj\r\nT:34344:shared-obj\r\nT:39640:shared-obj\r\nT:40036:shared-obj\r\nT:40372:shared-obj\r\n} Leave StartAndWaitForTasks\r\nFinal count: 0\r\n<\/pre>\n<h2>Passing an object to a background thread<\/h2>\n<p>Okay, so let&#8217;s say you&#8217;re not using the PPL, but explicit threads instead. In this case, using <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh920601.aspx\"><code>std::thread<\/code><\/a> and <code>shared_ptr<\/code> is the way to go:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;Windows.h&gt;\r\n#include &lt;thread&gt;\r\n\r\n\/\/ ...\r\nthread CreateMyThread()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    MyClassSPtr sp = make_shared&lt;MyClass&gt;(L&quot;used-by-thread&quot;);\r\n    return thread(&#x5B;](MyClassSPtr sp)\r\n    {\r\n        Sleep(1000);\r\n        DWORD id = GetCurrentThreadId();\r\n        wcout &lt;&lt; L&quot;Thread &quot; &lt;&lt; id &lt;&lt; L&quot; using &quot; &lt;&lt; sp-&gt;get_Name() &lt;&lt; endl;\r\n    }, sp);\r\n}\r\n\r\nvoid CreateAndWaitForMyThread()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    thread myThread = CreateMyThread();\r\n    myThread.join();\r\n}\r\n\r\nint wmain(int argc, wchar_t ** argv)\r\n{\r\n    CreateAndWaitForMyThread();\r\n    wcout &lt;&lt; L&quot;Final count: &quot; &lt;&lt; Counter::N &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>The output shows a similar situation as in the previous example where the object goes out of scope and is deleted shortly after the thread ends:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{ Enter CreateAndWaitForMyThread\r\n{ Enter CreateMyThread\r\nMyClass:used-by-thread\r\n} Leave CreateMyThread\r\nThread 41764 using used-by-thread\r\n~MyClass:used-by-thread\r\n} Leave CreateAndWaitForMyThread\r\nFinal count: 0\r\n<\/pre>\n<h2>Passing an object to a background thread (legacy)<\/h2>\n<p>Fine, you don&#8217;t want to use <code>std::thread<\/code>. You can modify the above sample to use the raw Win32 calls (e.g. <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms682453(v=vs.85).aspx\"><code>CreateThread<\/code><\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms687032(v=vs.85).aspx\"><code>WaitForSingleObject<\/code><\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms724211(v=vs.85).aspx\"><code>CloseHandle<\/code><\/a>) but it is somewhat more error prone. Basically, you need to ensure cleanup happens inside the thread on success or before you return\/throw on failure.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;Windows.h&gt;\r\n\r\n\/\/ ...\r\nDWORD WINAPI MyLegacyThreadFunc(void * obj)\r\n{\r\n    MyClassUPtr p(static_cast&lt;MyClass *&gt;(obj));\r\n    Sleep(1000);\r\n    DWORD id = GetCurrentThreadId();\r\n    wcout &lt;&lt; L&quot;Thread &quot; &lt;&lt; id &lt;&lt; L&quot; using &quot; &lt;&lt; p-&gt;get_Name() &lt;&lt; endl;\r\n    return 0;\r\n}\r\n\r\nHANDLE CreateMyLegacyThread()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    MyClassUPtr p = make_unique&lt;MyClass&gt;(L&quot;used-by-thread&quot;);\r\n    HANDLE handle = CreateThread(nullptr, 0, MyLegacyThreadFunc, p.get(), 0, nullptr);\r\n    if (!handle)\r\n    {\r\n        throw runtime_error(&quot;Failed!&quot;);\r\n    }\r\n\r\n    \/\/ Must release to avoid double-delete!\r\n    p.release();\r\n    return handle;\r\n}\r\n\r\nvoid CreateAndWaitForMyLegacyThread()\r\n{\r\n    FuncTrace t(__FUNCTIONW__);\r\n    HANDLE myThread = CreateMyLegacyThread();\r\n    WaitForSingleObject(myThread, INFINITE);\r\n    CloseHandle(myThread);\r\n}\r\n\r\nint wmain(int argc, wchar_t ** argv)\r\n{\r\n    CreateAndWaitForMyLegacyThread();\r\n    wcout &lt;&lt; L&quot;Final count: &quot; &lt;&lt; Counter::N &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>As expected, the thread will clean up the resource if it starts properly:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{ Enter CreateAndWaitForMyLegacyThread\r\n{ Enter CreateMyLegacyThread\r\n(Dynamic allocation)\r\nMyClass:used-by-thread\r\n} Leave CreateMyLegacyThread\r\nThread 33656 using used-by-thread\r\n~MyClass:used-by-thread\r\n(Dynamic deallocation)\r\n} Leave CreateAndWaitForMyLegacyThread\r\nFinal count: 0\r\n<\/pre>\n<p>That should be enough examples to give you an idea of <strong>smart<\/strong> ways to manage memory (or really, object ownership) in C++. Adoption of these kinds of modern coding practices should ensure safer, cleaner, less leaky applications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post I introduced some of the common cases for avoiding memory leaks with judicious use of unique_ptr. Of course, not all memory management situations are as straightforward, especially when dealing with low-level &#8220;C-style&#8221; APIs. Let&#8217;s explore a&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[91,101],"tags":[],"class_list":["post-2141","post","type-post","status-publish","format-standard","hentry","category-design","category-native"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2141"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2141\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2141"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}