Click here to Skip to main content
15,885,890 members
Articles / Programming Languages / C++

Memory Leak Detection

Rate me:
Please Sign up or sign in to vote.
4.71/5 (55 votes)
3 Jul 2009CPOL7 min read 479.1K   14.8K   217  
Adding Memory Leak Detection in your applications
/*************************************************************
 Author		: David A. Jones
 File Name	: MemLeakDetect.h
 Date		: July 30, 2004
 Synopsis	:		 
			A trace memory feature for source code to trace and
			find memory related bugs. 

 Future		:
				1) Memory corruption
				2) Freeing memory without allocating
				3) Freeing memory twice
				4) Not Freeing memory at all
				5) over running memory boundardies


****************************************************************/
#if !defined(MEMLEAKDETECT_H)
#define MEMLEAKDETECT_H

#define _CRTDBG_MAP_ALLOC

#include <map>
#define _CRTBLD
#include <windows.h>
#include "dbgint.h"
#include <ImageHlp.h>
#include <crtdbg.h>


#pragma comment( lib, "imagehlp.lib" )

using namespace std;

// if you want to use the custom stackwalker otherwise
// comment this line out
#define MLD_CUSTOMSTACKWALK			1
//
#define MLD_MAX_NAME_LENGTH			256
#define MLD_MAX_TRACEINFO			256
#define MLD_TRACEINFO_EMPTY			_T("")
#define MLD_TRACEINFO_NOSYMBOL		_T("?(?)")

#ifdef  MLD_CUSTOMSTACKWALK
#define MLD_STACKWALKER				symStackTrace2
#else
#define MLD_STACKWALKER				symStackTrace
#endif

#define AfxTrace MyTrace

typedef DWORD ADDR;

class CMemLeakDetect
{
	public:

		typedef struct 	{
				ADDRESS				addrPC;
				ADDRESS				addrFrame;
			
		} STACKFRAMEENTRY;

		typedef struct { 
				void*				address;
				DWORD				size;
				TCHAR				fileName[MLD_MAX_NAME_LENGTH];
				DWORD				lineNumber;
				DWORD				occurance;
				STACKFRAMEENTRY		traceinfo[MLD_MAX_TRACEINFO];

		} AllocBlockInfo;

		//typedef int POSITION;
		typedef map<LPVOID, AllocBlockInfo>				KEYMAP;
		typedef map<LPVOID, AllocBlockInfo>::iterator	POSITION;
		typedef pair<LPVOID, AllocBlockInfo>			KEYVALUE;

		class CMapMem
		{
			public:

				KEYMAP			m_Map;
				POSITION		m_Pos;

				inline BOOL Lookup(LPVOID pAddr,  AllocBlockInfo& aInfo) { 

					m_Pos = m_Map.find(pAddr);
					//
					if (m_Pos == m_Map.end())
					{
						return FALSE;
					}
					//
					pAddr = m_Pos->first;
					aInfo = m_Pos->second;

					return TRUE;
				};

				inline POSITION end() { 

					return m_Map.end(); 
				};

				inline void RemoveKey(LPVOID pAddr) { 
					
					m_Map.erase(pAddr);
				};

				inline void RemoveAll() {
					m_Map.clear();
				};

				void SetAt(LPVOID pAddr, AllocBlockInfo& aInfo) {

					m_Map[pAddr] = aInfo;
				};

				inline POSITION GetStartPosition() { 
					POSITION pos = m_Map.begin(); 
					return pos;
				};

				inline void GetNextAssoc(POSITION& pos, LPVOID& rAddr, AllocBlockInfo& aInfo) {

					rAddr = pos->first;
					aInfo = pos->second;
					pos++;
				};

				void InitHashTable(int preAllocEntries, BOOL flag) 	{
					 preAllocEntries	= NULL;
					 flag				= NULL;
				};

		};

		CMemLeakDetect();
		~CMemLeakDetect();
		void Init();
		void End();
		void addMemoryTrace(void* addr,  DWORD asize,  TCHAR *fname, DWORD lnum);
		void redoMemoryTrace(void* addr,  void* oldaddr, DWORD asize,  TCHAR *fname, DWORD lnum);
		void removeMemoryTrace(void* addr, void* realdataptr);
		void cleanupMemoryTrace();
		void dumpMemoryTrace();
		//

		//CMap<LPVOID, LPVOID, AllocBlockInfo, AllocBlockInfo> m_AllocatedMemoryList;
		CMapMem			 m_AllocatedMemoryList;
	DWORD memoccurance;
	bool  isLocked;
	//
	private:

		BOOL initSymInfo(TCHAR* lpUserPath);
		BOOL cleanupSymInfo();
		void symbolPaths( TCHAR* lpszSymbolPaths);
		void symStackTrace(STACKFRAMEENTRY* pStacktrace);
		void symStackTrace2(STACKFRAMEENTRY* pStacktrace);
		BOOL symFunctionInfoFromAddresses(ULONG fnAddress, ULONG stackAddress, char* lpszSymbol);
		BOOL symSourceInfoFromAddress(UINT address, TCHAR* lpszSourceInfo);
		BOOL symModuleNameFromAddress(UINT address, TCHAR* lpszModule);

		HANDLE				m_hProcess;
		PIMAGEHLP_SYMBOL	m_pSymbol;
		DWORD				m_dwsymBufSize;
};
#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions