[Gelöst] MSVC9 - Memory Leak Detection
-
Hi,
ich wollte gern mal ein wenig Memory Leak Detection in mein Projekt einbauen. Jetzt hab ich mich ein wenig an der MS Doku orientiert. Da steht auch das durch definieren des Macros _CRTDBG_MAP_ALLOC man eine etwas detailierte Ausgabe des Memory Dumps bekommt. Leider ist dem aber nicht so, muss man noch irgendwas anderes zuschalten damit es genauer wird? Gerade die Ausgabe in welcher Datei/Zeile das new benutzt und später versehentlich nicht mehr freigegeben wurde ist doch von interesse. Leider bekomm ich nur die "gepacktere" Variante ausgegeben. Hab auch schon versucht direkt per /D das Macro zu definieren, leider ohne Erfolg.
Hier mal ein kleines Beispiel welches bei mir leider nur die "Minimal" Ausgabe macht.#if defined(_DEBUG) # define _CRTDBG_MAP_ALLOC # include <crtdbg.h> #endif #include <iostream> int main(int argc, char* argv[]) { std::cout << ">>>>> allocate int memory" << std::endl; int* a = new int[10]; #if defined(_DEBUG) _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); std::cout << ">>>>> make mem snapshot 1" << std::endl; _CrtMemState s1; _CrtMemCheckpoint(&s1); std::cout << ">>>>> dump mem snapshot 1" << std::endl; _CrtMemDumpStatistics(&s1); #endif std::cout << ">>>>> allocate byte memory" << std::endl; char* s = new char[32]; #if defined(_DEBUG) std::cout << ">>>>> make mem snapshot 2" << std::endl; _CrtMemState s2, s3; _CrtMemCheckpoint(&s2); std::cout << ">>>>> compare mem snapshot 1 and 2" << std::endl; if (_CrtMemDifference(&s3, &s1, &s2)) { std::cout << ">>>>> difference found! dump difference statistics" << std::endl; _CrtMemDumpStatistics(&s3); } std::cout << ">>>>> dump mem leaks" << std::endl; _CrtDumpMemoryLeaks(); #endif std::cout << ">>>>> delete int memory" << std::endl; delete[] a; std::cout << ">>>>> delete byte memory" << std::endl; delete[] s; std::cin.get(); return 0; }
Ausgabe vom _CrtMemDumpStatistics(&s1); (Zeile 21):
0 bytes in 0 Free Blocks. 40 bytes in 1 Normal Blocks. 12517 bytes in 99 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 13267 bytes. Total allocations: 29089 bytes.
Ausgabe vom _CrtMemDumpStatistics(&s3); (Zeile 35):
0 bytes in 0 Free Blocks. 32 bytes in 1 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 0 bytes. Total allocations: 32 bytes.
Ausgabe vom _CrtDumpMemoryLeaks(); (Zeile: 39), Hier würde ich mir wünschen das die Ausgabe ein wenig gesprächiger ist:
Detected memory leaks! Dumping objects -> {125} normal block at 0x00335228, 32 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD {124} normal block at 0x003351C0, 40 bytes long. Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD Object dump complete.
Gut Schuß
VuuRWerK
-
Nimm doch einfach Visual Leak Detector.
-
Ok, den hatte ich auch schon mal gefunden aber noch nicht benutzt. Ich probier den einfach mal.
Gut Schuß
VuuRWerK
-
Benutze einfach _CRTDBG_MAP_ALLOC
http://msdn.microsoft.com/de-de/library/e5ewb1h3(VS.80).aspx
http://www.codeproject.com/kb/debug/tracer.aspx
-
@Martin Richter: Vielen Dank für den Tipp, aber das hab ich bereits (siehe mein Code im ersten Post) und deswegen wundert es mich ja umso mehr das es nur die "minimal" Ausgabe macht ...
Liegt es eventuell daran weil ich VS2008 auf Win7 verwende? Kann es mir eigentlich nicht vorstellen aber Ihr kennt das ja sicher mit den Pferden und der Apotheke@TyRoXx: VLD hat auch nicht funktioniert. Sobald ich VLD einbinde entläd es meine DLL sofort nach einbinden von meiner Host-Anwendung wieder o.O
Möglichweise kommt VLD mit/in DLLs nicht zurecht.Ich wollte eigentlich verhindern selber einen Memory-Tracker zu schreiben aber anscheinend bleibt mir nix anderes übrig. Schade.
Gut Schuß
VuuRWerK
-
Hast Du wirklich http://www.codeproject.com/kb/debug/tracer.aspx angesehen?
BTW: Wenn man die MFC verwendets bekommt man das alles frei Haus.
-
Ja na klar hab ich, deswegen schrieb ich auch das ich eigentlich erstmal kein eigenen schreiben wollte sondern auf Platformeigene Angebote zurückgreifen wollte.
Nein kein MFC, ISO-C++
Derzeit aber erstmal nur auf Windows später aber auch auf Linux. Nur wollt ich gern einen Memory-Leak Detector einbauen um von vornherein welche auszuschließen.
Gut Schuß
VuuRWerK
-
Sorry! Ich habe Dir scheinbar den falschen Link aus Code-Project gegeben.
Mit dem benutzt Du die CRT-Debug Tools.
http://www.codeproject.com/KB/debug/consoleleak.aspx
-
Aaahh! Danke es geht! Ich wusste doch das es mit new zu tun hat das man dafür noch was machen muss damits einwandfrei funktioniert ^^
Danke!
Gut Schuß
VuuRWerK[edit]
Es ist aber wirklich wichtig dass das ganze in einem extra Header steht, sonst ist es nicht kombilierbar!Für die Nachwelt
#ifndef __MEMORY_HPP__ #define __MEMORY_HPP__ #if defined(_DEBUG) # define _CRTDBG_MAP_ALLOC # include <crtdbg.h> void* operator new(size_t nSize, char const* lpszFileName, int nLine) { return ::operator new(nSize, 1, lpszFileName, nLine); } # define DEBUG_NEW new(THIS_FILE, __LINE__) # define MALLOC_DBG(x) _malloc_dbg(x, 1, THIS_FILE, __LINE__); # define malloc(x) MALLOC_DBG(x) # define new DEBUG_NEW #endif #endif // __MEMORY_HPP__
Und in jede *.cpp Datei:
#if defined(_DEBUG) # include "memory.hpp" # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
Wobei ich mir mal was einfallen lasse das man das eventuell ohne dem Extra definieren von THIS_FILE machen kann. Gemacht wird es ja nur weil sonst __FILE__ in 2 Macros verwendet werden würde und somit nur die Header-Datei als Filename gespeichert wird.
[/edit][edit2]
Ok, es ist einfacher als gedachtMan kann THIS_FILE einfach weglassen und in den Macros durch __FILE__ ersetzen. Mir fiel auf das es in 2 verschiedenen Macros verwendet wird die man aber selber aufruft und somit immer da wo man auch allokiert. Demnach steht in filename dann auch immer der richtige Name
[/edit2]