Jump to content
  • Advertisement
Sign in to follow this  
Wavesonics

C++ Tips on debugging memory corruption

This topic is 4260 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a very bad bug that I'm almost certain is stemming from memory corruption. I run a whole bunch of delete and delete [] and then some time very shortly afterwards the whole program crashes at a random point. Thats the tell tale signs of memory corruption as far as I know. So I was wondering if any one had any good tips on trying to locate or detect these types of bugs. Anything at all, I've tried a lot of things but maybe theres some basic technique people use that I don't know so please, anything no matter how simple tell me how you guys usually track these bugs.

Share this post


Link to post
Share on other sites
Advertisement
I (and many other people who know what they're doing) generally sidestep this by using the "basic technique" of RAII to avoid creating the problems in the first place. Show the code, and I'll try to show how these things can be fixed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Wavesonics
I have a very bad bug that I'm almost certain is stemming from memory corruption.

I run a whole bunch of delete and delete [] and then some time very shortly afterwards the whole program crashes at a random point. Thats the tell tale signs of memory corruption as far as I know.

So I was wondering if any one had any good tips on trying to locate or detect these types of bugs. Anything at all, I've tried a lot of things but maybe theres some basic technique people use that I don't know so please, anything no matter how simple tell me how you guys usually track these bugs.


It really depends on what system you are using to develop your code on. If it is Visual Studio then it has some pretty good CRT debug memory tools that you can enable - they will slow your code down a lot but it can do heap checks to make sure that any allocation/deallocation hasn't blown the heap and it also puts guard bands around allocations to make sure that you haven't walked off the end of an array and so on.

On top of that I also use a memory manager by Paul Nettle:

http://www.flipcode.org/cgi-bin/fcarticles.cgi?show=64444

to track all allocations and deallocations - its pretty good at what it does.

And finally, for the extreme bugs (i.e. those that are really hard to find) I start using PCLint... but I have to be desperate to get to this point since running PCLint on your code is like having the harshest critic look at your code and find nothing good about it.

Share this post


Link to post
Share on other sites
Awesome, ya I had to go through a bit to find that memory manager, but I finially got it.

I've never used MSVC++ but it seems like there is quite a bit of code that is specific to the MS compiler.

But uh... wow i sound like a n00b. guess i am... How do you use it?

Share this post


Link to post
Share on other sites
So I had an idea, I decided to override the global new and delete operators to keep a count, then at certain times print out the total:


// ===============================================
// I put this in a header which all files include:
// ===============================================
#ifndef MEMREPORT
#define MEMREPORT

#include <new>
#include <cstdlib>

extern int32_t *g_iNew;
extern int32_t *g_iDelete;

extern void* operator new ( size_t size );

extern void operator delete (void *p);

extern void memReport();

#endif

// =================================
// Then I define them in my main.cpp
// in the global scope
// =================================

int32_t *g_iNew;
int32_t *g_iDelete;

void* operator new ( size_t size ) {
++(*g_iNew);

void *p = malloc( size );
return p;
}

void operator delete (void *p) {
++(*g_iDelete);
free( p );
}


// And finial I init them in main
int main(int argc, char *argv[]) {
g_iNew = (int32_t*)malloc( sizeof(int32_t) );
(*g_iNew) = 0;
g_iDelete = (int32_t*)malloc( sizeof(int32_t) );
(*g_iDelete) = 0;

...

}




But the reports are producing what seem to be none sense results.

They are in the hundreds of thousands, and TOTALLY inconsistent, every run they are different. I print the memory report before a delete and immediately after and the number has changed by many hundreds and even new has changed. So clearly my code is ef-ed.

Can any of you see a problem with it?

[edit]
These are what the results are right now when they should at the most be around 100 News:

Heap Memory Report:
Total New: 23235
Total Del: 1094
[/edit]

Share this post


Link to post
Share on other sites
If your trying to keep track of allocations and deallocations, you should also define new[] and delete[]. Why did you make g_iNew and g_iDelete pointers, anyway? A simple "int g_iNew = 0;" should work better (and they don't need to be known outside main.cpp - what's the code for memReport()?). If your trying to cut memory corruption, a good way to see if its happening is at the end of main(), g_iNew should equal g_iDelete. If it does not, than they are news that did not recieve a delete, or vice-versa.

And another thing: freeing already-freed data tends not to work.
Smart pointers, if you haven't heard of them, tend to work very well in situations like these.

Make sure every new() has a delete().

Is the program trying to access freed-data? Or null or dangling pointers?

I wonder if initializing them in main is causing havoc - or if they are being used before main() activates.

Share this post


Link to post
Share on other sites
Ya idk, i had them declared like that originally, but when it wasn't working i tried pointers wondering if it might affect the linkage.

I reverted it back now, but still get the same none sense inconsistent results.

But your very correct I need to over ride new [] and delete [] as well. Still though, not even my new and delete over rides are working how I would think they should at the moment.

Share this post


Link to post
Share on other sites
Memory breakpoints are useful for tracking down memory corruption problems. In VC++ you create a data breakpoint and have it fire if the value at a memory address that appears to be getting corrupted changes. You don't say what debugger you're using but I imagine most debuggers on the PC should have a similar facility.

Share this post


Link to post
Share on other sites
I've had quite a few circumstances where bugs like this rear their ugly heads (through maintaining someone else's code).

While the above posters are correct that there are a plethora of tools available for helping to detect these errors, nothing is fool-proof. I've had a lot of experience trying to get a tool to work and it just ends up costing me more time.

The best thing to do (especially since you don't seem to be using VS) is to comment out all but one section of code. Verify that the problem doesn't exist anymore (if it does then you've narrowed it down to the stuff that isn't commented), then uncomment your code one piece at a time until the bug shows up. You can usually use this technique to narrow the culprit down to one allocation or deallocation (or a copy somewhere).

Hope this helps...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!