Sign in to follow this  

memory leak somewhere

This topic is 4303 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

Running my prog in debug mode works fine without error or warning. When I run the program in release, however, this msg comes up. It appears right after the client connects to another client. First-chance exception at 0x71a92413 in Shooter.exe: 0xC0000005: Access violation writing location 0x00130000. First-chance exception at 0x00409869 in Shooter.exe: 0xC0000005: Access violation reading location 0x00000002. Then it repeats this until the program is exited: First-chance exception at 0x00000000 in Shooter.exe: 0xC0000005: Access violation reading location 0x00000000. The memory leak is getting detected, but its not giving me any indication as to where it is. I know there are libraries in the compiler that may be able to help me, can anybody point me towards those functions? When it attempts to read from location 0x00000002, I'm assuming that is my structure with 2 shorts; pretty much the only time I'm reading from a memory address that is not divisible by 4. Any suggestions? Why would running debug mode not detect this memory leak?

Share this post


Link to post
Share on other sites
The typical problem when switching from Debug to Release is that variables don't automatically get initialised to zero in release.

Check for this. Hope that helps,

Dave

Share this post


Link to post
Share on other sites
I always have compiler warnings on the highest level. It will warn if there is a chance something is not initialized before use, plus there are run-time checks to make sure variables are getting set before they are used.

Share this post


Link to post
Share on other sites
Quote:
Original post by davidlkoenig
Turn "Generate Debug Info" on for your release build. This will help give you more useful info in the debugger when it does in fact crash.


It was on, thats why it was generating the errors in the first place.

Share this post


Link to post
Share on other sites
BTW, these are not memory leaks. A memory leak happens when you are unable to deallocate (and reuse) memory, usually because the pointer to the allocation is overwritten. Here is a simple example of a memory leak:
    int * pAlloc = new int[ 1048576 ]; // A 4MB allocation
pAlloc = &some_other_int; // The allocation is now "leaked"

// At this point, the address of the allocation is lost, and so the memory can
// never be deallocated and reused.
The problem you are having is dereferencing an invalid pointer. The usual reasons are:
  • referencing deallocated memory,
  • dereferencing an uninitialized pointer,
  • bad pointer arithmetic,
  • dereferencing a pointer that has been set to 0 (to indicate that the memory was deallocated),
  • dereferencing a pointer parameter whose value is 0, and
  • this == 0.

Share this post


Link to post
Share on other sites
You can use the CRT debugging functions. However these are reserved for _DEBUG builds.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_debug_functions.asp

If you're using DirectX in your app, you can turn on "Break on memory errors" through the DirectX applet in control panel. Make sure you're running the debug directx runtimes as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by ussnewjersey4
Try using the Fluid Studios memory manager. It can detect memory leaks and keeps track of all memory allocations, and it may be able to detect your memory problems. Its also extremly easy to use: just include the headers.
Fluid Studios Memory Manager


I'm looking into that now. I don't see it helping me much because I don't create memory dynamically too often. And I don't use _alloca() anymore. I'm assuming my problem is some bad ptr math, but I don't see where, and I don't see why it wouldn't cause a problem in debug mode.

Yeah, I know it is not exactly a leak. Its most likely me derefencing null memory somehow.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
... or possibly that you have under-allocated memory some place and everybody sees the last part of that memory block *magically* changing with time. Most of the time, it's one of those "off-by-one" size calculation errors. Some compilers add debugging info to allocated blocks in _DEBUG mode. One way to be sure is to tweak your "Release" settings to allow for debugging information to be generated and you turn off optimizations. You thus have a debuggable "Release" build. Another method is to add 4K to each malloc() call in turn and run the app to see which one is likely being under-allocated.

Share this post


Link to post
Share on other sites
So I gave up on the one program because all it did was overload the new/delete/malloc/free functions and operators. My problem is not with a new/delete call (of course not, that would be too simple). In fact, no where in my code do I call new or any other allocator. All my dynamic data is stored in vectors and hash_multimaps.

If you look at the first 2 memory errors that occur, the first is an invalid write to 0x0130000 or whatever. The second is an invalid read from 0x2. Just 2. Which leads me to believe that I using a certain data structure that begins with a 2 byte variable and is followed by another 2 byte variable or is packed to 1 or 2. [I actually do pack almost all of my structures because I send them over the network]. But as far as I can see, the only way I'm accessing memory at 0x2 is by acquiring a null ptr to a structure with a member starting 2 bytes into the structure.

I've been asserting that my ptr's are not null and now I'm returning from the function if my ptr's are null (because asserts don't work in release).

It is possible that the error is not in my code, but I doubt it because the prog locks up right when the clients connect.

Anyways, more suggestions are always welcome.

Share this post


Link to post
Share on other sites
So hind-sight is 20/20. I've heard that enough. The solution was to duplicate my Release build (where the prog. broke), then slightly increase typechecks and debug info on that build. This build deemed, "MyDebug" didn't take long to narrow down the exact compiler setting that causes the bug. The problem is I'm not sure how to fixe it.

The compiler setting is "Basic Runtime Checks:" The possible values are, stack frames, unititialized vars, none, or both. When I put this on "Stack Frames", I'm assuming it will check all stack frames and correct on-the-fly.

So I'm guessing my problem is that I'm corrupting the stack somewhere. I do do a bit of recursion, but nothing too hard (at least not for me).

Suggestions?

[Edited by - blaze02 on March 7, 2006 10:00:23 AM]

Share this post


Link to post
Share on other sites
Well.. here it is. The bane of my existence for the past 12 hours.


void jMsging::NatPunch(const SOCKADDR_IN * sockaddr)
{
int oldTTL, TTL = 2, size;

getsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&oldTTL, &size);
setsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&TTL, sizeof(TTL));
Send(0, 0, sockaddr);
setsockopt(thesocket, IPPROTO_IP, IP_TTL, (char*)&oldTTL, sizeof(oldTTL));
}



Seems harmless at first glance. And it was only called one time. Thats all it needed to kick the stack pointer in the balls. A cheap shot for the lock up.
So this is how you punch through a NAT with UDP. You lower the ttl, send a zero-byte packet, then up the ttl. Can you see the problem?

getsockopt is used for a variety of options, that is why oldTTL must be typecast to a char*. The problem is that the (size) param is an in/out variable. Much like the recvfrom() network call. People ask why the value has to be a pointer to a size. The answer is that size is not only the size of the value loaded into oldTTL, but also the maximum size that can be loaded in. (size) must be initialized to sizeof(oldTTL) to get rid of the bug.
Final thoughts: why is getsockopt trying to load MORE than 4 bytes into oldTTL just because the size said it could. TTL ranges from 0 -> 255. How was it using more than 4 bytes.

Share this post


Link to post
Share on other sites
That's a silly assumption anyway. What if size somehow ended up being 0? Then it wouldn't set any bytes and oldTTL would end up containing garbage. You have to set size to something to make sure that doesn't happen, and if you're going to do that, you might as well set it to the correct value.

Share this post


Link to post
Share on other sites
Quote:
Original post by smart_idiot
That's a silly assumption anyway. What if size somehow ended up being 0? Then it wouldn't set any bytes and oldTTL would end up containing garbage. You have to set size to something to make sure that doesn't happen, and if you're going to do that, you might as well set it to the correct value.


That was the problem. I said that I fixed it by initializing size to sizeof(oldTTL).

Share this post


Link to post
Share on other sites

This topic is 4303 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this