{"id":21883,"date":"2008-06-23T10:00:00","date_gmt":"2008-06-23T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/06\/23\/just-because-youre-using-a-smart-pointer-class-doesnt-mean-you-can-abdicate-understanding-what-it-does\/"},"modified":"2008-06-23T10:00:00","modified_gmt":"2008-06-23T10:00:00","slug":"just-because-youre-using-a-smart-pointer-class-doesnt-mean-you-can-abdicate-understanding-what-it-does","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080623-00\/?p=21883","title":{"rendered":"Just because you&#039;re using a smart pointer class doesn&#039;t mean you can abdicate understanding what it does"},"content":{"rendered":"<p>\nIt&#8217;s great when you have a tool to make programming easier,\nbut you still must understand what it does or you&#8217;re\njust replacing one set of problems with another set of more subtle\nproblems.\nFor example, we discussed earlier the importance of knowing\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">\nwhen your destructor runs<\/a>.\nHere&#8217;s another example, courtesy of my colleague Chris Ashton.\nThis was posted\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#515856\">\nas a Suggestion Box entry<\/a>,\nbut it&#8217;s pretty much a complete article on its own.\n<\/p>\n<blockquote CLASS=\"m\">\n<p>\nI came across an interesting bug this weekend\nthat I&#8217;ve never seen described anywhere else,\nI thought it might be good fodder for your blog.\n<\/p>\n<p>\nWhat do you suppose the following code does?\n<\/p>\n<pre>\nCComBSTR bstr;\nbstr = ::SysAllocStringLen(NULL, 100);\n<\/pre>\n<ol type=\"a\">\n<li>Allocates a <code>BSTR<\/code> 100 characters long.\n<li>Leaks memory and,\n    if you&#8217;re really lucky,\n    opens the door for an insidious memory corruption.\n<\/ol>\n<p>\nObviously I&#8217;m writing here,\nso the answer cannot be&nbsp;A.  It is, in fact,&nbsp;B.\n<\/p>\n<p>\nThe key is that <code>CComBSTR<\/code> is involved here,\nso <code>operator=<\/code> is being invoked.\nAnd <code>operator=<\/code>, as you might recall,\ndoes a deep copy of the entire string,\nnot just a shallow copy of the <code>BSTR<\/code> pointer.\nBut how long does <code>operator=<\/code> think the string is?\nWell, since <code>BSTR<\/code> and <code>LPCOLESTR<\/code> are equivalent\n(at least as far as the C++ compiler is concerned),\nthe argument to <code>operator=<\/code> is an <code>LPCOLESTR<\/code> &ndash;\nso <code>operator=<\/code> naturally tries to use the\n<code>wcslen<\/code> length of the string,\nnot the <code>SysStringLen<\/code> length.\nAnd in this case, since the string is uninitialized,\n<code>wcslen<\/code> often returns a much smaller value than\n<code>SysStringLen<\/code> would.\nAs a result, the original 100-character string is leaked,\nand you get back a buffer that can only hold, say, 25 characters.\n<\/p>\n<p>\nThe code you <i>really<\/i> want here is:\n<\/p>\n<pre>\nCComBSTR bstr;\nbstr.Attach(::SysAllocStringLen(NULL, 100));\n<\/pre>\n<p>\nOr:\n<\/p>\n<pre>\nCComBSTR bstr(100);\n<\/pre>\n<p>\nI&#8217;m still a big fan of smart pointers\n(surely the hours spent finding this bug\nwould have been spent finding memory leaks\ncaused by other incautious programmers),\nbut this example gives pause &ndash;\n<code>CComBSTR<\/code> and some OLE calls just don&#8217;t mix.\n<\/p>\n<\/blockquote>\n<p>\nAll I can add to this story is an exercise:\nChris writes,\n&#8220;Since the string is uninitialized,\n<code>wcslen<\/code> often returns a much smaller value than\n<code>SysStringLen<\/code> would.&#8221;\nCan it possibly return a <i>larger<\/i> value?\nIs there a potential read overflow here?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s great when you have a tool to make programming easier, but you still must understand what it does or you&#8217;re just replacing one set of problems with another set of more subtle problems. For example, we discussed earlier the importance of knowing when your destructor runs. Here&#8217;s another example, courtesy of my colleague Chris [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-21883","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It&#8217;s great when you have a tool to make programming easier, but you still must understand what it does or you&#8217;re just replacing one set of problems with another set of more subtle problems. For example, we discussed earlier the importance of knowing when your destructor runs. Here&#8217;s another example, courtesy of my colleague Chris [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21883","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=21883"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21883\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=21883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21883"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}