Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Finding a memory leak in MSVC?

This topic is 5090 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''m getting the following memory leak:
Detected memory leaks!
Dumping objects ->
{42} normal block at 0x003607B8, 12 bytes long.
 Data: <  6   6     > B8 07 36 00 B8 07 36 00 CD CD CD CD 
Object dump complete.
 
And I can''t figure out what it''s coming from. I tried to start my winmain like this:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	_CrtSetBreakAlloc(42);
and then I ran in debug, but no breakpoint was ever set... is there any other way to find the source?

Share this post


Link to post
Share on other sites
Advertisement
In all honesty, the best way to find memory leaks in a program is by using a tool called Bounds Checker by Numega. Unfortunately it is about 500 bucks, but it will find it I promise. Basically you run the program with it in the background, and it keeps track of all your memory and bounds. If you don''t free, violate some memory, write out of bounds...anything it will catch it!

If you are really in a bind, you can download their evaluation copy (15 days or something) and use that. Unfortunately after 15 days they annoy the hell out of you about it. The only way to kill the annoying messages is to reinstall VC++. But hay, if it means that much to you :D



Sincerely,
Randy Trulson
www.GamePotato.com
www.NeuronGames.com

Share this post


Link to post
Share on other sites
quote:
Original post by Neophyte
Insert the following at the top of your main-file:

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif


And the following at the start of your main (or WinMain) method:

#ifndef NDEBUG
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(flag);
#endif


Although you probably already did the last part, so only redefining new is likely to be necessary.

This should tell at you at which line in which file the memory that leaks was allocated.

Hope that helps,
- Neophyte


(Taken from his reply to my thread on pretty much the same question here.)

Worked beautifully for me anyway. Once you know where the problem starts it''s a lot easier to find where it should be resolved.

-Arek the Absolute

Share this post


Link to post
Share on other sites
quote:
Original post by Arek the Absolute
quote:
Original post by Neophyte
Insert the following at the top of your main-file:

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif


And the following at the start of your main (or WinMain) method:

#ifndef NDEBUG
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(flag);
#endif


Although you probably already did the last part, so only redefining new is likely to be necessary.

This should tell at you at which line in which file the memory that leaks was allocated.

Hope that helps,
- Neophyte


(Taken from his reply to my thread on pretty much the same question here.)

Worked beautifully for me anyway. Once you know where the problem starts it''s a lot easier to find where it should be resolved.

-Arek the Absolute


Hmm, when I tried it in MSVC 6 SP5, I got the following:

c:\program files\microsoft visual studio\vc98\include\new(35) : error C2059: syntax error : ''constant''
c:\program files\microsoft visual studio\vc98\include\new(35) : error C2091: function returns function
c:\program files\microsoft visual studio\vc98\include\new(35) : error C2809: ''operator new'' has no formal parameters
c:\program files\microsoft visual studio\vc98\include\new(36) : error C2059: syntax error : ''constant''
c:\program files\microsoft visual studio\vc98\include\new(37) : error C2091: function returns function
c:\program files\microsoft visual studio\vc98\include\new(37) : error C2556: ''void *(__cdecl *__cdecl operator new(void))(unsigned int,const struct std::nothrow_t &)'' : overloaded function differs only by return type from ''void *(__cdecl *__cdecl op
erator new(void))(unsigned int)''
c:\program files\microsoft visual studio\vc98\include\new(35) : see declaration of ''new''
c:\program files\microsoft visual studio\vc98\include\new(41) : error C2059: syntax error : ''constant''
c:\program files\microsoft visual studio\vc98\include\new(42) : error C2091: function returns function
c:\program files\microsoft visual studio\vc98\include\new(42) : error C2556: ''void *(__cdecl *__cdecl operator new(void))(unsigned int,void *)'' : overloaded function differs only by return type from ''void *(__cdecl *__cdecl operator new(void))(unsig
ned int)''
c:\program files\microsoft visual studio\vc98\include\new(35) : see declaration of ''new''
c:\program files\microsoft visual studio\vc98\include\new(42) : error C2809: ''operator new'' has no formal parameters
c:\program files\microsoft visual studio\vc98\include\new(42) : error C2065: ''_P'' : undeclared identifier
c:\program files\microsoft visual studio\vc98\include\memory(16) : error C2059: syntax error : ''constant''
c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2091: function returns function
c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2784: ''void *(__cdecl *__cdecl operator new(void))(unsigned int,class std::allocator<`template-parameter257''> &)'' : could not deduce template argument for ''void *(__cdecl *)(u
nsigned int,class std::allocator<_Ty> &)'' from ''void *(__cdecl *)(unsigned int)''
c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2785: ''void *(__cdecl *__cdecl operator new(void))(unsigned int,class std::allocator<`template-parameter257''> &)'' and ''void *(__cdecl *__cdecl operator new(void))(unsigned int
)'' have different return types
c:\program files\microsoft visual studio\vc98\include\memory(16) : see declaration of ''new''
c:\program files\microsoft visual studio\vc98\include\memory(17) : error C2809: ''operator new'' has no formal parameters
c:\program files\microsoft visual studio\vc98\include\memory(20) : error C2954: template definitions cannot nest


Here''s the code I used:

(In the headers)

#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h> // Memory leak detection

#define new new(_NORMAL_BLOCK,__FILE__, __LINE__) // memory leak stuff

#endif // _DEBUG




.............

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
_CrtSetBreakAlloc(44);
////////////////// Enable memory leak detection ///////////

#ifdef _DEBUG
_CrtDumpMemoryLeaks();
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
#endif

Share this post


Link to post
Share on other sites
Uhm, all of those solutions are unnecessary.

There''s a tutorial on flipcode that shows a very, very easy to implement set of functions that will catch every memory leak (unless you do something stupid like use malloc()).

Just override the global new and delete operators. Simple, simple, simple.

Share this post


Link to post
Share on other sites
quote:
Original post by sirSolarius

Hmm, when I tried it in MSVC 6 SP5, I got the following:
[errors]



I won't try and fool anyone into thinking I'm qualified to explain why some of this works and why it doesn't. I only think I have the general gist of it, so maybe someone else can pick up the strings. For now though, I can show you this code from my own project which uses this method of monitoring memory leaks, and compiles perfectly well in VC++ 6.0.

app.cpp

#include <afxwin.h>
#include <winsock2.h>

#include "app.h"
#include "window.h"


void DetectMemoryLeaks(){

#ifndef NDEBUG
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(flag);
#endif

}

BOOL App::InitInstance(){
DetectMemoryLeaks();

Window *window = new Window();

window->Create(NULL,"OMG A TITLE!");
window->ShowWindow(SW_SHOW);
window->UpdateWindow();

m_pMainWnd = window;

return true;

}

App application;


sock.cpp (just a small cpp file that uses the other part of the code)

#include <winsock2.h>
#include <crtdbg.h>

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif
#include "sock.h"

Socket::Socket(){

status = 0;

}

bool Socket::BindSocket(){

if(bind(sock, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
return false;
}

return true;

}


For me, the easiest way to prevent getting errors using this method has been to just split up the source files and only use parts of it at a time. I use the DetectMemoryLeaks() function only once and only from the InitInstance of the application, and none of the other source files know about or have access to the function. At the same time, it does NOT include the #define new new(_NORMAL_BLOCK,__FILE__, __LINE__) This is fine however, because my App class is simple enough I'm not really worried about memory leaks in that particular file, but including the overloaded new operator in all the other source files works just fine.

Sorry I haven't answered why, but that seems to make it work for me.

-Arek the Absolute

[edit]- formatting annoyances

[edited by - Arek the Absolute on June 12, 2004 1:00:12 AM]

Share this post


Link to post
Share on other sites
I use and recommend Paul Nettle''s memory manager. After I''ve done a new chunk of code I run my exe and see whether it has discovered any leaks (it writes out a log file). Much easier to track the leaks down then.

Share this post


Link to post
Share on other sites
Hmm, trying to debug the new overriding thing has been tough for me, so I''m trying out Paul Nettle''s memory manager.

quote:
Original post by Strewth
I use and recommend Paul Nettle''s memory manager. After I''ve done a new chunk of code I run my exe and see whether it has discovered any leaks (it writes out a log file). Much easier to track the leaks down then.


I have a problem running his code, too!

Here''s all I did:

// Includes

#define WIN32_LEAN_AND_MEAN // Trims fat from windows.h

#include <windows.h>

#ifdef _DEBUG
#include "MemCheck/mmgr.h" // Memory leak stuff

#endif // _DEBUG



#include "Vector3.h"

// Managers

#include "SettingsManager.h" // Maintains various settings

#include "WindowManager.h" // Creates & sets up the window

#include "ErrorManager.h" // Error handling code

#include "MemoryManager.h" // Memory management

#include "RenderManager.h" // Rendering manager


// Data structures

#include "InputKeymap.h" // Keymapping & input manager



And then I get these errors:

c:\program files\microsoft visual studio\vc98\include\stdlib.h(281) : warning C4002: too many actual parameters for macro ''calloc''
c:\program files\microsoft visual studio\vc98\include\stdlib.h(281) : error C2059: syntax error : ''string''
c:\program files\microsoft visual studio\vc98\include\stdlib.h(283) : error C2062: type ''void'' unexpected
c:\program files\microsoft visual studio\vc98\include\stdlib.h(298) : error C2059: syntax error : ''string''
c:\program files\microsoft visual studio\vc98\include\stdlib.h(306) : error C2059: syntax error : ''string''
c:\program files\microsoft visual studio\vc98\include\new(34) : error C2544: expected '')'' for operator ''()''
c:\program files\microsoft visual studio\vc98\include\new(34) : error C2146: syntax error : missing '';'' before identifier ''m_setOwner''
c:\program files\microsoft visual studio\vc98\include\new(34) : warning C4229: anachronism used : modifiers on data are ignored
c:\program files\microsoft visual studio\vc98\include\new(34) : error C2182: ''()'' : illegal use of type ''void''
c:\program files\microsoft visual studio\vc98\include\new(34) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

KutatasEngine.exe - 8 error(s), 2 warning(s)


Any idea what''s causing that?

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!