Memory leaks
-
Hi! I have created a very simple project called Test in Microsoft Visual Studio 2005 of type Win32 Console Application, using MFC,which looks like this:
#include "stdafx.h" #include "Test.h" #define _CRTDBG_MAP_ALLOC #include "stdlib.h" #include "crtdbg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { _tprintf(_T("Fatal Error: MFC initialization failed\n")); nRetCode = 1; } else _CrtDumpMemoryLeaks( ); return nRetCode; }
After compiling and executing it in Debug mode, in the Output window of the IDE appeared this information:'Test.exe': Loaded 'E:\Test\debug\Test.exe', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugMFC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_c8452471\mfc80ud.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcr80d.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\sockspy.dll', Binary was not built with debug information. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFCLOC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_3415f6d0\mfc80ENU.dll', Binary was not built with debug information. Detected memory leaks! Dumping objects -> {61} client block at 0x003A3298, subtype c0, 64 bytes long. a CDynLinkLibrary object at $003A3298, 64 bytes long Object dump complete. The program '[2164] Test.exe: Native' has exited with code 0 (0x0).
As you can see, I haven't allocated any memory on the heap. The only pieces of code added by me were #define _CRTDBG_MAP_ALLOC, the include lines for < -
Hi! I have created a very simple project called Test in Microsoft Visual Studio 2005 of type Win32 Console Application, using MFC,which looks like this:
#include "stdafx.h" #include "Test.h" #define _CRTDBG_MAP_ALLOC #include "stdlib.h" #include "crtdbg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { _tprintf(_T("Fatal Error: MFC initialization failed\n")); nRetCode = 1; } else _CrtDumpMemoryLeaks( ); return nRetCode; }
After compiling and executing it in Debug mode, in the Output window of the IDE appeared this information:'Test.exe': Loaded 'E:\Test\debug\Test.exe', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugMFC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_c8452471\mfc80ud.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcr80d.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\sockspy.dll', Binary was not built with debug information. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFCLOC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_3415f6d0\mfc80ENU.dll', Binary was not built with debug information. Detected memory leaks! Dumping objects -> {61} client block at 0x003A3298, subtype c0, 64 bytes long. a CDynLinkLibrary object at $003A3298, 64 bytes long Object dump complete. The program '[2164] Test.exe: Native' has exited with code 0 (0x0).
As you can see, I haven't allocated any memory on the heap. The only pieces of code added by me were #define _CRTDBG_MAP_ALLOC, the include lines for <For an MFC app, you don't need a _tmain() entry point. Use the CWinApp::InitInstance() and CWinApp::ExitInstance() overrides for initialization and cleanup. If you absolutely MUST have your own entry point then you'll need to look at the source code for MFC's entry-point implementation and make sure you are covering all initialization and cleanup. If the only reason you need to override the entry point is to check for memory leaks then you can use a static object like your CWinApp object. I use this in my app module:
#ifdef _DEBUG
class _MemStateCheck
{
public:
CMemoryState oldMemState, newMemState, diffMemState;\_MemStateCheck(); ~\_MemStateCheck();
};
_MemStateCheck::_MemStateCheck()
{
oldMemState.Checkpoint();
}_MemStateCheck::~_MemStateCheck()
{
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "************************\n" );
TRACE( "Memory leaks Detected\n" );
TRACE( "************************\n" );
diffMemState.DumpStatistics();
diffMemState.DumpAllObjectsSince();
}
else
{
TRACE( "************************\n" );
TRACE( "No memory leaks Detected\n" );
TRACE( "************************\n" );
}
}_MemStateCheck MemCheckObj;
#endif //#ifdef _DEBUG -
For an MFC app, you don't need a _tmain() entry point. Use the CWinApp::InitInstance() and CWinApp::ExitInstance() overrides for initialization and cleanup. If you absolutely MUST have your own entry point then you'll need to look at the source code for MFC's entry-point implementation and make sure you are covering all initialization and cleanup. If the only reason you need to override the entry point is to check for memory leaks then you can use a static object like your CWinApp object. I use this in my app module:
#ifdef _DEBUG
class _MemStateCheck
{
public:
CMemoryState oldMemState, newMemState, diffMemState;\_MemStateCheck(); ~\_MemStateCheck();
};
_MemStateCheck::_MemStateCheck()
{
oldMemState.Checkpoint();
}_MemStateCheck::~_MemStateCheck()
{
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "************************\n" );
TRACE( "Memory leaks Detected\n" );
TRACE( "************************\n" );
diffMemState.DumpStatistics();
diffMemState.DumpAllObjectsSince();
}
else
{
TRACE( "************************\n" );
TRACE( "No memory leaks Detected\n" );
TRACE( "************************\n" );
}
}_MemStateCheck MemCheckObj;
#endif //#ifdef _DEBUGThank you for your time!
-
Hi! I have created a very simple project called Test in Microsoft Visual Studio 2005 of type Win32 Console Application, using MFC,which looks like this:
#include "stdafx.h" #include "Test.h" #define _CRTDBG_MAP_ALLOC #include "stdlib.h" #include "crtdbg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { _tprintf(_T("Fatal Error: MFC initialization failed\n")); nRetCode = 1; } else _CrtDumpMemoryLeaks( ); return nRetCode; }
After compiling and executing it in Debug mode, in the Output window of the IDE appeared this information:'Test.exe': Loaded 'E:\Test\debug\Test.exe', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugMFC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_c8452471\mfc80ud.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcr80d.dll', Symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded. 'Test.exe': Loaded 'C:\WINDOWS\system32\sockspy.dll', Binary was not built with debug information. 'Test.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFCLOC_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_3415f6d0\mfc80ENU.dll', Binary was not built with debug information. Detected memory leaks! Dumping objects -> {61} client block at 0x003A3298, subtype c0, 64 bytes long. a CDynLinkLibrary object at $003A3298, 64 bytes long Object dump complete. The program '[2164] Test.exe: Native' has exited with code 0 (0x0).
As you can see, I haven't allocated any memory on the heap. The only pieces of code added by me were #define _CRTDBG_MAP_ALLOC, the include lines for <There is no problem creating an app like this. The memory leak is a side effect of the MFC dlls unloading and is on shutdown only (and is likely due to the restrictions on unloading DLLs, rather than MFC itself.) If you link statically, the leak will go away.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
There is no problem creating an app like this. The memory leak is a side effect of the MFC dlls unloading and is on shutdown only (and is likely due to the restrictions on unloading DLLs, rather than MFC itself.) If you link statically, the leak will go away.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
Thank you very much for the explanation and for the solution, at the same time!