title: Pointer corrupted while returning from a function
body: <p><strong>TL;DR</strong>: When I run my C++ program on a Mac under OS X Yosemite, a pointer gets corrupted while a function is returning. How do I stop it from happening? (and why?)</p>
  
  <hr>
  
  <p>In <a href="https://gist.github.com/diazona/ba7f270d3e1763e6abf8" rel="nofollow">this sample program</a>, I have a data structure of type <code>category_map&lt;T&gt;</code> which is effectively just a</p>
  
  <pre><code>map&lt;string, list&lt;pair&lt;string, T&gt; &gt; &gt;
  </code></pre>
  
  <p>The <code>category_map</code> class has a couple of methods, including <code>get(string&amp; name)</code> which pulls the <code>list</code> stored under the given <code>name</code> and returns the <code>T</code> from the first element of that list. In my case, <code>T</code> is a pointer type. The pointer that the code retrieves from the first <code>pair</code> in the <code>list</code> - that'd be <code>p</code> in the code listing below - is valid. A debugger session shows that the value of <code>p</code> on the last line of the function - the closing brace, before destructors run - is a valid memory location like, say, <code>0x100809c00</code>.</p>
  
  <pre><code>T&amp; get(const string&amp; name) const {
      cerr &lt;&lt; "searching for " &lt;&lt; name &lt;&lt; endl;
      typename super::const_iterator map_iterator = super::find(name);
      // the real code doesn't assume it will be found
      list_type the_list = map_iterator-&gt;second;
      T&amp; p = the_list.front().second;
      cerr &lt;&lt; "found " &lt;&lt; val_loc_string&lt;T&gt;(p) &lt;&lt; endl;
      return p;
  }
  </code></pre>
  
  <p>However, when I compile and run the code on a Mac (OS X Yosemite), but not on Linux, somewhere in the process of cleaning up from this function, something writes to the same location in memory, so that the returned pointer - stored in the variable <code>ip</code> in the next code listing below - is corrupted. For example, it might become <code>0x3000100809c00</code> or <code>0x5000100809c00</code>. The corrupted pointer is always the original pointer with one or a few extra bits set in the 2nd-most-significant byte of the 8-byte address.</p>
  
  <pre><code>int main(const int argc, const char** argv) {
      category_map&lt;int*&gt; imap;
      int a;
      imap.add("Q1", "m", &amp;a);
      imap.add("Q1", "r", &amp;a);
      imap.add("Q2", "m", &amp;a);
  
      int* ip = imap.get("Q1");
      cerr &lt;&lt; "return value: " &lt;&lt; val_loc_string&lt;int*&gt;(ip) &lt;&lt; endl;
      cout &lt;&lt; *ip &lt;&lt; endl;
  }
  </code></pre>
  
  <p>Using GDB (installed through MacPorts) I've identified the specific instruction that writes the extra bits to the memory location.</p>
  
  <pre><code>   0x00007fff93188279:  cmp    $0x2,%eax
     0x00007fff9318827c:  jb     0x7fff9318828d
     0x00007fff9318827e:  shl    $0x4,%rax
  =&gt; 0x00007fff93188282:  mov    %r10w,-0x2(%rax,%rdx,1)
     0x00007fff93188288:  mov    %r10w,0x10(%rdx)
     0x00007fff9318828d:  test   %r10w,%r10w
     0x00007fff93188291:  jne    0x7fff93188299
  </code></pre>
  
  <p>(<a href="https://gist.github.com/diazona/ba7f270d3e1763e6abf8#file-gdb_dump-s" rel="nofollow">more context</a>) but this is not much help because it's not part of a C/C++ function, I'm not fluent enough in assembly to understand what it's doing on a large scale, and the <a href="https://gist.github.com/diazona/ba7f270d3e1763e6abf8#file-stack_trace-txt" rel="nofollow">backtrace</a> is garbage so I can't put the code in context. (I've also captured the <a href="https://gist.github.com/diazona/ba7f270d3e1763e6abf8#file-registers-txt" rel="nofollow">values of the registers</a> just prior to the instruction that corrupts the pointer, in case that helps for some reason.)</p>
  
  <p>Since I instantiate <code>category_map&lt;T&gt;</code> only with pointer types, I <em>could</em> change the return type of <code>get</code> to <code>T</code> (instead of <code>T&amp;</code>) and that does appear to solve (or at least work around) the problem. But it makes the data structure more generally useful if it can hold large objects and return them by reference, and I would think that should be possible. Plus, whatever error I've made in coding this, I would like to understand so I don't make it again. Can anyone point out what I did wrong, and the right way to fix it without changing the API?</p>