27 static _CrtMemState mem_chk_p1,
31 static HANDLE mem_log_file = 0;
36 #define CrtSetDebugField(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
37 #define CrtClrDebugField(a) _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
40 static void heapdump()
49 while ((heapstatus = _heapwalk( &hinfo )) == _HEAPOK) {
50 sprintf_s(report,
"%6s block at %Fp of size %4.4X\n",
51 ( hinfo._useflag == _USEDENTRY ?
"USED" :
"FREE" ),
52 hinfo._pentry, hinfo._size);
54 _RPT0(_CRT_WARN, report);
56 if (hinfo._useflag == _USEDENTRY)
62 sprintf_s(report,
"------\nUsed Blocks: %d\nAvail Blocks: %d\nTotal Blocks: %d\n", used, avail, used+avail);
63 _RPT0(_CRT_WARN, report);
67 _RPT0(_CRT_WARN,
"OK - empty heap\n" );
70 _RPT0(_CRT_WARN,
"OK - end of heap\n" );
73 _RPT0(_CRT_WARN,
"ERROR - bad pointer to heap\n" );
76 _RPT0(_CRT_WARN,
"ERROR - bad start of heap\n" );
79 _RPT0(_CRT_WARN,
"ERROR - bad node in heap\n" );
90 if (!filename || !strlen(filename))
91 filename =
"memdbg.txt";
93 mem_log_file = CreateFile(filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
96 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
97 _CrtSetReportFile(_CRT_WARN, mem_log_file);
98 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
99 _CrtSetReportFile(_CRT_ERROR, mem_log_file);
100 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
101 _CrtSetReportFile(_CRT_ASSERT, mem_log_file);
104 _CrtMemCheckpoint(&mem_chk_p1);
115 CloseHandle(mem_log_file);
118 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
119 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
120 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
121 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
122 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
123 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
134 if (! _CrtCheckMemory()) {
135 _RPT0(_CRT_ERROR,
"\n\nMemory Check Failed.\n");
150 if (mem_chk_level <
PERIODIC)
return;
152 _RPT0(_CRT_WARN,
"\n\nMemory Checkpoint:\n"
153 "--------------------------------------------------\n");
156 _CrtMemCheckpoint(&mem_chk_p2);
157 _CrtMemDifference(&s, &mem_chk_p1, &mem_chk_p2);
158 _CrtMemDumpStatistics(&s);
160 memcpy(&mem_chk_p1, &mem_chk_p2,
sizeof(mem_chk_p1));
170 if (mem_chk_level <
PERIODIC)
return;
172 _RPT0(_CRT_WARN,
"\n\nMemory Stats:\n"
173 "--------------------------------------------------\n");
176 _CrtMemCheckpoint(&s);
177 _CrtMemDumpStatistics(&s);
187 _RPT0(_CRT_WARN,
"\n\nMemory Dump Leaks:\n"
188 "--------------------------------------------------\n");
189 _CrtDumpMemoryLeaks();
203 switch (mem_chk_level) {
204 case MAXIMAL: CrtSetDebugField(_CRTDBG_CHECK_ALWAYS_DF);
205 case PERIODIC: CrtSetDebugField(_CRTDBG_DELAY_FREE_MEM_DF);
206 case LEAKS: CrtSetDebugField(_CRTDBG_LEAK_CHECK_DF);