<p>So, I need some help. I am working on a project in C++. However, I think I have somehow managed to corrupt my heap. This is based on the fact that I added an <code>std::string</code> to a class and assigning it a value from another <code>std::string</code>:</p>

<pre><code>std::string hello = "Hello, world.\n";
/* exampleString = "Hello, world.\n" would work fine. */
exampleString = hello;
</code></pre>

<p>crashes on my system with a stack dump. So basically I need to <strong>stop</strong> and go through all my code and memory management stuff and find out where I've screwed up. The codebase is still small (about 1000 lines), so this is easily do-able. </p>

<p>Still, I'm over my head with this kind of stuff, so I thought I'd throw it out there. I'm on a Linux system and have poked around with <code>valgrind</code>, and while not knowing completely what I'm doing, it did report that the <code>std::string</code>'s destructor was an invalid free. I have to admit to getting the term 'Heap Corruption' from a Google search; any general purpose articles on this sort of stuff would be appreciated as well.</p>

<p>(In before <code>rm -rf ProjectDir</code>, do again in C# :D)</p>

<p>EDIT:
I haven't made it clear, but what I'm asking for are ways an advice of diagnosing these sort of memory problems. I know the std::string stuff is right, so it's something I've done (or a bug, but there's Not A Problem With Select). I'm sure I could check the code I've written up and you very smart folks would see the problem in no time, but I want to add this kind of code analysis to my 'toolbox', as it were.</p>

[{'answer_id': 7536, 'author': 'JimDaniel', 'author_id': 63, 'author_profile': 'https://Stackoverflow.com/users/63', 'pm_score': 0, 'selected': False, 'text': '<p>As far as I can tell your code is correct. Assuming exampleString is an std::string that has class scope like you describe, you ought to be able to initialize/assign it that way. Perhaps there is some other issue? Maybe a snippet of actual code would help put it in context.</p>\n\n<p>Question: Is exampleString a pointer to a string object created with new?</p>\n'}, {'answer_id': 7543, 'author': 'Derek Park', 'author_id': 872, 'author_profile': 'https://Stackoverflow.com/users/872', 'pm_score': 1, 'selected': False, 'text': "<p>It could be heap corruption, but it's just as likely to be stack corruption.  Jim's right.  We really need a bit more context.  Those two lines of source don't tell us much in isolation.  There could be any number of things causing this (which is the real joy of C/C++).</p>\n\n<p>If you're comfortable posting your code, you could even throw all of it up on a server and post a link.  I'm sure you'd gets lots more advice that way (some of it undoubtedly unrelated to your question).</p>\n"}, {'answer_id': 7549, 'author': 'roo', 'author_id': 716, 'author_profile': 'https://Stackoverflow.com/users/716', 'pm_score': 1, 'selected': False, 'text': '<p>Your code as I can see has no errors. As has been said more context is needed.</p>\n<p>If you haven\'t already tried, install gdb (the gcc debugger) and compile the program with -g. This will compile in debugging symbols which gdb can use. Once you have gdb installed run it with the program (gdb &lt;your_program&gt;). <a href="http://web.archive.org/web/20130512080834/http://www.cs.vassar.edu:80/%7Ecs331/gdbtutorial.html" rel="nofollow noreferrer">This</a> is a useful cheatsheat for using gdb.</p>\n<p>Set a breakpoint for the function that is producing the bug, and see what the value of exampleString is. Also do the same for whatever parameter you are passing to exampleString. This should at least tell you if the std::strings are valid.</p>\n<p>I found the answer from <a href="https://stackoverflow.com/questions/5727/understanding-pointers">this article</a> to be a good guide about pointers.</p>\n'}, {'answer_id': 7559, 'author': 'Bernard', 'author_id': 61, 'author_profile': 'https://Stackoverflow.com/users/61', 'pm_score': 1, 'selected': False, 'text': "<p>The code was simply an example of where my program was failing (it was allocated on the stack, Jim). I'm not actually looking for 'what have I done wrong', but rather 'how do I diagnose what I've done wrong'. Teach a man to fish and all that. Though looking at the question, I haven't made that clear enough. Thank goodness for the edit function. :')</p>\n\n<p>Also, I actually fixed the std::string problem. How? By replacing it with a vector, compiling, then replacing the string again. It <em>was</em> consistently crashing there, and that fixed even though it...couldn't. There's something nasty there, and I'm not sure what. I did want to check the one time I manually allocate memory on the heap, though:</p>\n\n<pre><code> this-&gt;map = new Area*[largestY + 1];\n for (int i = 0; i &lt; largestY + 1; i++) {\n     this-&gt;map[i] = new Area[largestX + 1];\n }\n</code></pre>\n\n<p>and deleting it:</p>\n\n<pre><code>for (int i = 0; i &lt; largestY + 1; i++) {\n    delete [] this-&gt;map[i];\n}\ndelete [] this-&gt;map;\n</code></pre>\n\n<p>I haven't allocated a 2d array with C++ before. It seems to work.</p>\n"}, {'answer_id': 7566, 'author': 'Derek Park', 'author_id': 872, 'author_profile': 'https://Stackoverflow.com/users/872', 'pm_score': 3, 'selected': False, 'text': '<p>Oh, if you want to know how to debug the problem, that\'s simple.  First, get a dead chicken.  Then, <a href="http://c2.com/cgi/wiki?VoodooChickenCoding" rel="noreferrer">start shaking it</a>.</p>\n\n<p>Seriously, I haven\'t found a consistent way to track these kinds of bugs down.  Because there\'s so many potential problems, there\'s not a simple checklist to go through.  However, I would recommend the following:</p>\n\n<ol>\n<li>Get comfortable in a debugger.</li>\n<li>Start tromping around in the debugger to see if you can find anything that looks fishy.  Check especially to see what\'s happening during the <code>exampleString = hello;</code> line.</li>\n<li>Check to make sure it\'s actually crashing on the <code>exampleString = hello;</code> line, and not when exiting some enclosing block (which could cause destructors to fire).</li>\n<li>Check any pointer magic you might be doing.  Pointer arithmetic, casting, etc.</li>\n<li>Check all of your allocations and deallocations to make sure they are matched (no double-deallocations).</li>\n<li>Make sure you aren\'t returning any references or pointers to objects on the stack.</li>\n</ol>\n\n<p>There are lots of other things to try, too.  I\'m sure some other people will chime in with ideas as well.</p>\n'}, {'answer_id': 7567, 'author': 'Derek Park', 'author_id': 872, 'author_profile': 'https://Stackoverflow.com/users/872', 'pm_score': 1, 'selected': False, 'text': "<blockquote>\n  <p>Also, I actually fixed the std::string problem. How? By replacing it with a vector, compiling, then replacing the string again. It was consistently crashing there, and that fixed even though it...couldn't. There's something nasty there, and I'm not sure what.</p>\n</blockquote>\n\n<p>That sounds like you really did shake a chicken at it.  If you don't know <em>why</em> it's working now, then it's still broken, and pretty much guaranteed to bite you again later (after you've added even more complexity).</p>\n"}, {'answer_id': 7573, 'author': 'Orion Edwards', 'author_id': 234, 'author_profile': 'https://Stackoverflow.com/users/234', 'pm_score': 2, 'selected': False, 'text': '<p>Some places to start:</p>\n\n<p>If you\'re on windows, and using visual C++6 (I hope to god nobody still uses it these days) it\'s implentation of std::string is not threadsafe, and can lead to this kind of thing.</p>\n\n<p><a href="http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html" rel="nofollow noreferrer">Here\'s an article I found which explains a lot of the common causes of memory leaks and corruption.</a></p>\n\n<p>At my previous workplace we used Compuware Boundschecker to help with this. It\'s commercial and very expensive, so may not be an option.</p>\n\n<p>Here\'s a couple of free libraries which may be of some use</p>\n\n<p><a href="http://www.codeguru.com/cpp/misc/misc/memory/article.php/c3745/" rel="nofollow noreferrer">http://www.codeguru.com/cpp/misc/misc/memory/article.php/c3745/</a></p>\n\n<p><a href="http://www.codeproject.com/KB/cpp/MemLeakDetect.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/cpp/MemLeakDetect.aspx</a></p>\n\n<p>Hope that helps. Memory corruption is a sucky place to be in!</p>\n'}, {'answer_id': 7584, 'author': 'Mark Harrison', 'author_id': 116, 'author_profile': 'https://Stackoverflow.com/users/116', 'pm_score': 1, 'selected': False, 'text': '<p>Run Purify.</p>\n\n<p>It is a near-magical tool that will report when you are clobbering memory you shouldn\'t be touching, leaking memory by not freeing things, double-freeing, etc.</p>\n\n<p>It works at the machine code level, so you don\'t even have to have the source code.</p>\n\n<p>One of the most enjoyable vendor conference calls I was ever on was when Purify found a memory leak in their code, and we were able to ask, "is it possible you\'re not freeing memory in your function foo()" and hear the astonishment in their voices.</p>\n\n<p>They thought we were debugging gods but then we let them in on the secret so they could run Purify before we had to use their code. :-)</p>\n\n<p><a href="http://www-306.ibm.com/software/awdtools/purify/unix/" rel="nofollow noreferrer">http://www-306.ibm.com/software/awdtools/purify/unix/</a></p>\n\n<p>(It\'s pretty pricey but they have a free eval download)</p>\n'}, {'answer_id': 7613, 'author': 'Greg Hewgill', 'author_id': 893, 'author_profile': 'https://Stackoverflow.com/users/893', 'pm_score': 1, 'selected': False, 'text': "<p>One of the debugging techniques that I use frequently (except in cases of the most extreme weirdness) is to divide and conquer. If your program currently fails with some specific error, then divide it in half in some way and see if it still has the same error. Obviously the trick is to decide where to divide your program!</p>\n\n<p>Your example as given doesn't show enough context to determine where the error might be. If anybody else were to try your example, it would work fine. So, in your program, try removing as much of the extra stuff you didn't show us and see if it works then. If so, then add the other code back in a bit at a time until it starts failing. Then, the thing you just added is probably the problem.</p>\n\n<p>Note that if your program is multithreaded, then you probably have larger problems. If not, then you should be able to narrow it down in this way. Good luck!</p>\n"}, {'answer_id': 7695, 'author': 'Josh', 'author_id': 257, 'author_profile': 'https://Stackoverflow.com/users/257', 'pm_score': 6, 'selected': True, 'text': '<p>These are relatively cheap mechanisms for possibly solving the problem:</p>\n\n<ol>\n<li>Keep an eye on my <a href="https://stackoverflow.com/questions/1069/heap-corruption-under-win32-how-to-locate">heap corruption question</a> - I\'m updating with the answers as they shake out.  The first was balancing <code>new[]</code> and <code>delete[]</code>, but you\'re already doing that.</li>\n<li>Give <a href="http://valgrind.org/" rel="nofollow noreferrer">valgrind</a> more of a go; it\'s an excellent tool, and I only wish it was available under Windows.  I only slows your program down by about half, which is pretty good compared to the Windows equivalents.</li>\n<li>Think about using the <a href="http://code.google.com/p/google-perftools/" rel="nofollow noreferrer">Google Performance Tools</a> as a replacement malloc/new.</li>\n<li>Have you cleaned out all your object files and started over?  Perhaps your make file is... "suboptimal"</li>\n<li>You\'re not <code>assert()</code>ing enough in your code.  How do I know that without having seen it?  Like flossing, no-one <code>assert()</code>s enough in their code.  Add in a validation function for your objects and call that on method start and method end.</li>\n<li>Are you <a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.0/cpp/Invocation.html#Invocation" rel="nofollow noreferrer">compiling -wall</a>?  If not, do so.</li>\n<li>Find yourself a lint tool like <a href="http://www.gimpel.com/" rel="nofollow noreferrer">PC-Lint</a>.  A small app like yours might fit in the <a href="http://gimpel-online.com/cgi-bin/genPage.py?srcFile=diy.cpp&amp;cgiScript=analyseCode.py&amp;title=Blank+Slate+(C%2B%2B)+&amp;intro=An+empty+page+in+which+to+write+your+own+C%2B%2B+code.&amp;compilerOption=co-gcc.lnt+co-gnu3.lnt&amp;includeOption=%7B%7BquotedIncludeOption%7D%7D" rel="nofollow noreferrer">PC-lint demo</a> page, meaning no purchase for you!</li>\n<li>Check you\'re NULLing out pointers after deleteing them.  Nobody likes a dangling pointer.  Same gig with declared but unallocated pointers.</li>\n<li>Stop using arrays.  Use a <a href="http://en.wikipedia.org/wiki/Vector_(STL)" rel="nofollow noreferrer">vector</a> instead.</li>\n<li>Don\'t use raw pointers.  Use a <a href="http://en.wikipedia.org/wiki/Smart_pointer" rel="nofollow noreferrer">smart pointer</a>.  Don\'t use <code>auto_ptr</code>!  That thing is... surprising; its semantics are very odd.  Instead, choose one of the <a href="http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/smart_ptr.htm" rel="nofollow noreferrer">Boost smart pointers</a>, or something out of <a href="http://en.wikipedia.org/wiki/Loki_(C%2B%2B)" rel="nofollow noreferrer">the Loki library</a>.</li>\n</ol>\n'}, {'answer_id': 20857, 'author': '17 of 26', 'author_id': 2284, 'author_profile': 'https://Stackoverflow.com/users/2284', 'pm_score': 1, 'selected': False, 'text': '<p>Other than tools like Boundschecker or Purify, your best bet at solving problems like this is to just get really good at reading code and become familiar with the code that you\'re working on.</p>\n\n<p>Memory corruption is one of the most difficult things to troubleshoot and usually these types of problems are solved by spending hours/days in a debugger and noticing something like "hey, pointer X is being used after it was deleted!".</p>\n\n<p>If it helps any, it\'s something you get better at as you gain experience.</p>\n\n<p>Your memory allocation for the array looks correct, but make sure you check all the places where you access the array too.  </p>\n'}, {'answer_id': 71983, 'author': 'Richard Corden', 'author_id': 11698, 'author_profile': 'https://Stackoverflow.com/users/11698', 'pm_score': 3, 'selected': False, 'text': '<p>We once had a bug which eluded all of the regular techniques, valgrind, purify etc.  The crash only ever happened on machines with lots of memory and only on large input data sets.</p>\n\n<p>Eventually we tracked it down using debugger watch points.  I\'ll try to describe the procedure here:</p>\n\n<p>1) Find the cause of the failure.  It looks from your example code, that the memory for "exampleString" is being corrupted, and so cannot be written to.  Let\'s continue with this assumption.</p>\n\n<p>2) Set a breakpoint at the last known location that "exampleString" is used or modified without any problem.</p>\n\n<p>3) Add a watch point to the data member of \'exampleString\'.  With my version of g++, the string is stored in <code>_M_dataplus._M_p</code>.  We want to know when this data member changes.  The GDB technique for this is:</p>\n\n<pre><code>(gdb) p &amp;exampleString._M_dataplus._M_p\n$3 = (char **) 0xbfccc2d8\n(gdb)  watch *$3\nHardware watchpoint 1: *$3\n</code></pre>\n\n<p>I\'m obviously using linux with g++ and gdb here, but I believe that memory watch points are available with most debuggers.</p>\n\n<p>4) Continue until the watch point is triggered:</p>\n\n<pre><code>Continuing.\nHardware watchpoint 2: *$3\n\nOld value = 0xb7ec2604 ""\nNew value = 0x804a014 ""\n0xb7e70a1c in std::string::_M_mutate () from /usr/lib/libstdc++.so.6\n(gdb) where\n</code></pre>\n\n<p>The gdb <code>where</code> command will give a back trace showing what resulted in the modification.  This is either a perfectly legal modification, in which case just continue - or if you\'re lucky it will be the modification due to the memory corruption.  In the latter case, you should now be able to review the code that is <em>really</em> causing the problem and hopefully fix it.</p>\n\n<p>The cause of our bug was an array access with a negative index.  The index was the result of a cast of a pointer to an \'int\' modulos the size of the array.  The bug was missed by valgrind et al. as the memory addresses allocated when running under those tools was never "<code>&gt; MAX_INT</code>" and so never resulted in a negative index.</p>\n'}]
['https://Stackoverflow.com/questions/7525', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/61/']