In Windows Mobile, memory leakage is a serious problem due to the small memory size. The performance of tool detection is often not as good as expected. The following provides a method to increase the memory leakage detection in the Code:
Because memory leaks are generally caused by heap space memory leaks, We can reload the new method in C ++, as shown below:
# Ifndef _ debug
# DEFINE _ debug
# Endif
# Include "crtdbg. H"
# Define new (_ T (_ file _), _ line __)
Int winapi winmain (hinstance,
Hinstance hprevinstance,
Lptstr lpcmdline,
Int ncmdshow)
{
// Todo: Place code here.
_ Crtsetdbgflag (on );
Int * P = new int;
* P = 10;
Return 0;
}
_ Crtsetdbgflag (on); this actually only defines a class:
# DEFINE _ crtsetdbgflag (ignore )/
Garbagecollector GB;
This class marks a _ crtmemroot. In the new class, we mark the memory address in this tag. When the class is parsed, we will judge whether the mark exists, if delete is not called, the tag is not empty, so Memory leakage is detected.
The content of the crtdbg. h file is as follows:
/*************************************** **************************
Filename: crtdbg. h
Author: Ciprian miclaus (Ciprian_Miclaus@yahoo.com)
Description:
Detects memory leaks in EVC ++ almost the same way crtdbg does in VC ++.
At the end of program execution it will display in the debug window if
There were any memory leaks and how the memory looks so you can identify
Where your memory leak occurred. It will display in the debug window
Message saying no memory leaks detected if there are no memory leaks.
Similar to what crtdbg does in VC ++.
It will fail to display the line same as crtdbg does.
There are 3 simple steps in order to enable Memory Leak Detection:
1. Define _ debug
# DEFINE _ debug
2. Include "crtdbg. H"
# Include "crtdbg. H"
3. Let your first line in the code be:
_ Crtsetdbgflag (on );
Tips on debugging:
Tip 1:
Altho it doesn' t display the line where the memory leak occurred (read
Tip 2), the utility display the address in hexa, and you can add a small
Code to the operator new function, just after the first malloc:
If (retptr = (void *) 0x76da0)
Dumb instruction; <-place a breakpoint on this one
So you can detect easily which line of your code called the operator new
To allocate memory at the specified address and wasn' t freed.
Tip 2:
Here's a trick that allow you to get the correct line and filename where
The memory leak occurred. Define the following line in every file, or define
It In A. H and include it in every file where you want accurate line and
Filename:
# Define new (_ T (_ file _), _ line __)
Happy debugging!
License: Public Domain
Comments:
Please report any bugs to Ciprian_Miclaus@yahoo.com.
You can use and distribute this code freely, but please keep these
Few lines.
If you make any improvements, or have any ideas about how this code
Cocould be improved or just you feel you need to comment this code in
Any way, please send your comments, idea, imporvements to me to my
Email above.
The Code doesn' t detect memory leaks generated with C functions:
Malloc, calloc, free, but that can be done in the future. Let me know
And I will program it.
**************************************** ****************************/
# Ifndef _ crtdbg_header
# DEFINE _ crtdbg_header
# Ifdef _ debug
# Include <stdlib. h>
# Include <malloc. h>
# Include <string. h>
# Include <tchar. h>
# Include <dbgapi. h>
// Un-comment this line if you get an error:
// Unresolved... nkdbuplintfw...
// Extern "C" Void winapiv nkdbuplintfw (lpwstr lpszfmt ,...);
Struct _ crtfilename {
Unsigned short * _ crtname;
_ Crtfilename * _ crtnext;
};
Struct _ crtmem {
_ Crtfilename * _ crtfilename;
Int _ crtline;
Unsigned int _ crtmemlen;
Void * _ crtmemaddr;
_ Crtmem * _ crtnext;
};
Void * operator new (
Unsigned int s,
Unsigned short * Name,
Int line
);
Inline void * _ cdecl operator new (unsigned int S)
{Return: Operator new (S, (unsigned short *) _ file __, _ line __);}
Void _ cdecl operator Delete (void * pvmem );
Class garbagecollector {
Public:
Garbagecollector (){}
~ Garbagecollector ();
};
# DEFINE _ crtsetdbgflag (ignore )/
Garbagecollector GB;
_ Crtmem * _ crtmemroot = 0;
_ Crtfilename * _ crtfilenameroot = 0;
Unsigned long maxmem = 0;
Unsigned long currmem = 0;
Void * operator new (
Unsigned int s,
Unsigned short * Name,
Int line
)
{
Void * retptr = malloc (s );
If (retptr)
{
Currmem + = s;
If (currmem> maxmem)
{
Maxmem = currmem;
}
_ Crtmem * _ crtmemcell = (struct _ crtmem *) malloc (sizeof (_ crtmem ));
_ Crtmemcell-> _ crtline = line;
_ Crtmemcell-> _ crtmemlen = s;
_ Crtmemcell-> _ crtmemaddr = retptr;
_ Crtmemcell-> _ crtnext = 0;
_ Crtfilename * _ tmpcrtfilename;
For (_ tmpcrtfilename = _ crtfilenameroot; _ tmpcrtfilename & wcscmp (wchar_t *) Name, (const wchar_t *) _ tmpcrtfilename-> _ crtname ); _ tmpcrtfilename = _ tmpcrtfilename-> _ crtnext );
If (! _ Tmpcrtfilename)
{
Unsigned short * _ crtname = (unsigned short *) malloc (wcslen (wchar_t *) Name) + 1) * sizeof (unsigned short ));
Wcscpy (wchar_t *) _ crtname, (wchar_t *) Name );
_ Crtfilename * _ crtfilename = (struct _ crtfilename *) malloc (sizeof (_ crtfilename ));
_ Crtfilename-> _ crtname = _ crtname;
_ Crtfilename-> _ crtnext = 0;
If (! _ Crtfilenameroot)
_ Crtfilenameroot = _ crtfilename;
Else
{
For (_ tmpcrtfilename = _ crtfilenameroot; _ tmpcrtfilename-> _ crtnext; _ tmpcrtfilename = _ tmpcrtfilename-> _ crtnext );
_ Tmpcrtfilename-> _ crtnext = _ crtfilename;
}
_ Tmpcrtfilename = _ crtfilename;
}
_ Crtmemcell-> _ crtfilename = _ tmpcrtfilename;
If (! _ Crtmemroot)
{
_ Crtmemroot = _ crtmemcell;
}
Else
{
_ Crtmem * _ tmpmemptr;
For (_ tmpmemptr = _ crtmemroot; _ tmpmemptr-> _ crtnext; _ tmpmemptr = _ tmpmemptr-> _ crtnext );
_ Tmpmemptr-> _ crtnext = _ crtmemcell;
}
}
Return retptr;
}
Void _ cdecl operator Delete (void * pvmem)
{
If (pvmem)
{
_ Crtmem * _ tmpmem;
If (pvmem = _ crtmemroot-> _ crtmemaddr)
{
_ Tmpmem = _ crtmemroot;
_ Crtmemroot = _ crtmemroot-> _ crtnext;
Currmem-= _ tmpmem-> _ crtmemlen;
Free (_ tmpmem );
}
Else
{
For (_ tmpmem = _ crtmemroot; _ tmpmem-> _ crtnext & (_ tmpmem-> _ crtnext-> _ crtmemaddr! = Pvmem); _ tmpmem = _ tmpmem-> _ crtnext );
If (_ tmpmem-> _ crtnext)
{
_ Crtmem * _ tmpmem2;
_ Tmpmem2 = _ tmpmem-> _ crtnext;
_ Tmpmem-> _ crtnext = _ tmpmem2-> _ crtnext;
Currmem-= _ tmpmem2-> _ crtmemlen;
Free (_ tmpmem2 );
}
Else
Nkdbuplintfw (_ T ("% s (% I): Warning: deletes memory pointer not allocated with new! /N "), _ T (_ file _), _ line __);
}
Free (pvmem );
}
}
Garbagecollector ::~ Garbagecollector ()
{
If (! _ Crtmemroot)
Nkdbuplintfw (_ T ("no memory leaks detected! /N "));
Else
{
_ Crtmem * _ tmpmem;
Nkdbuplintfw (_ T ("detected memory leaks! /Ndumping objects->/N "));
For (_ tmpmem = _ crtmemroot; _ tmpmem = _ tmpmem-> _ crtnext ){
Nkdbuplintfw (_ T ("% s (% I): normal block at 0x % 08x, % I bytes long/n data <"), _ tmpmem-> _ crtfilename-> _ crtname, _ tmpmem-> _ crtline, _ tmpmem-> _ crtmemaddr, _ tmpmem-> _ crtmemlen );
Unsigned int _ length = _ tmpmem-> _ crtmemlen <100? _ Tmpmem-> _ crtmemlen: 50;
For (unsigned int I = 0; I <_ length; I ++)
Nkdbuplintfw (_ T ("% C"), * (char *) _ tmpmem-> _ crtmemaddr) + I ));
Nkdbuplintfw (_ T (">/N "));
}
}
_ Crtfilename * _ tmpname = _ crtfilenameroot;
For (; _ tmpname ;)
{
_ Crtfilenameroot = _ tmpname-> _ crtnext;
Free (_ tmpname-> _ crtname );
Free (_ tmpname );
_ Tmpname = _ crtfilenameroot;
}
Nkdbuplintfw (_ T ("Maximum free store memory allocated at a time: % lu! /N "), maxmem );
}
# Else
# DEFINE _ crtsetdbgflag (ignore)
# Endif // debug
# Endif // Header