Here is a simple memory leak automatic check mechanism. Applies only to single threaded cases. The working principle is to use the allocated memory in tandem with a two-way linked list, to release the memory from the chain list. Prints the memory that is not freed in the linked list when the program exits. Also saves the file name and line number in the memory block for locating the memory allocation address.
001//Placement_new.cpp:Defines The entry point for the console application.
002//
003
004 #include "stdafx.h"
005 #include
006 #include
007
008 #define ASSERT assert
009 Char buff[1024];
010
011 using namespace Std;
012
013 struct Memory_tag
014 {
015 int nsize;
016 Const char* Szfile;
017 int nline;
018 memory_tag* Pprev;
019 memory_tag* Pnext;
020};
021
022 Memory_tag G_header = {0, 0, 0, 0, 0};
023//Print out all memory not released
024 void Dumpunallocatedmem ()
025 {
026 for (memory_tag* pentry = G_header.pnext; pentry; pentry = pentry->pnext)
027 {
028 printf ("%s (%d): Leak%d bytes", Pentry->szfile? Pentry->szfile: "", Pentry->nline, pentry->nsize);
029}
030}
031//Statistics The number of memory blocks and bytes allocated
032 int C++ountofallocatedmem (void* pnsize= NULL)
033 {
034 int ncount = 0;
035 size_t allocated = 0;
036 for (memory_tag* pentry = G_header.pnext; pentry; pentry = pentry->pnext)
037 {
038 Allocated + + pentry->nsize;
039 ncount++;
040}
041 printf ("%d count,%d Total", ncount, allocated);
042 return ncount;
043}
24v
045//Implementation of a global operator new can have file names and line numbers as parameters
046 void* operator new (size_t size, const char* pszfile, int line)
047 {
048 size_t nrealsize = size + sizeof (MEMORY_TAG);
049 memory_tag* PTag = (memory_tag*) malloc (nrealsize);
050
051 ptag->nsize = nrealsize;
052 ptag->szfile = Pszfile;
053 Ptag->nline = line;
054//Insert Queue Head
055 if (g_header.pnext)
056 {
057 G_header.pnext->pprev = PTag;
058}
059 Ptag->pnext = G_header.pnext;
060 G_header.pnext = PTag;
061 Ptag->pprev = &g_header;
062
063 return PTag + 1;
064}
065
066 void* operator new (size_t size)
067 {
068 Return (operator new (size, __file__, __line__));
069}
070
071
072 void operator Delete (void* p, const char*, int line)
073 {
074 Delete p;
075}
076
077 void operator Delete (void* p)
078 {
079 memory_tag* PTag = (memory_tag*) ((char*) p)-sizeof (Memory_tag));
080//Removed from queue
081 Ptag->pprev->pnext = ptag->pnext;
082 if (ptag->pnext)
083 {
084 Ptag->pnext->pprev = ptag->pprev;
085}
086 free (PTag);
087}
088
089 class Object
090 {
091 Public:
092 Object ()
093 {
094 cout << "Object ' contructor." << Endl;
095}
096
097 ~object ()
098 {
099 cout << "Object ' destructor." << Endl;
100}
101
102 Char data[1024];
103};
104
#define NEW New (__file__, __line__)
106
_tmain Int (int argc, _tchar* argv[])
108 {
109 ASSERT (countofallocatedmem () = 0);
object* pobj = new (buff) Object;
111
112 Pobj->~object ();
113
114 Pobj = NEW (Object);
The Countofallocatedmem () = = 1);
116
117 Delete pobj;
118 ASSERT (countofallocatedmem () = 0);
119
Pobj = NEW Object;
121 ASSERT (Countofallocatedmem () = 1);
122 Delete pobj;
123 ASSERT (countofallocatedmem () = 0);
124
Pobj = NEW Object;
126
127 char* p = new char[968];
128 ASSERT (Countofallocatedmem () = 2);
129
130 Dumpunallocatedmem ();
131 return 0;
132}