Memory Leaks - wie feststellen?
-
Wie kann ich feststellen, ob mein Programm leakt? Ich kenn nur _CrtDumpMemoryLeaks(), aber das saugt ziemlich, weil
- es mir nicht anzeigt, wo im Code ich den Speicher allokiert habe
- es meckert, wenn ich irgendwo ne globale/statische string-Instanz habe, wo ich aber doch davon ausgehe, dass der Speicher am Ende wieder freigegeben wirdZumindest müsste ich mal wissen, wo der angeblich geleakte Speicher allokiert wird, dann kann ich immer noch entscheiden, ob der jetzt wirklich geleakt sein kann, oder ob der sicher noch freigegeben wird.
Am besten wäre es natürlich, wenn nur Speicher angezeigt wird, der nicht mehr referenziert wird.
-
Mein Visual Studio blättert eine ganze Anzahl an Memory Leaks herunter. Mit der Info kann ich momentan nix anfangen.
Bin deshalb sehr gespannt auf ein paar Antworten und Tipps hier
-
Hallo,
am einfachsten geht das natürlich mit einem Tool wie Rational Purify. Das ist allerdings nicht ganz billig (es gibt aber eine 14 Tage Ausprobierversion). Im Netz sollte man aber auch freie Alternativen finden.
Wie z.B. MemProf, Valgrind oder LeakTracer.PS: Da es hier wohl nicht darum geht, ein solches Tool in Standard-C++ selbst zu schreiben, verschiebe ich die Frage mal nach Rund um...
-
Auf die Suche nach den Programmstellen der Memeory-Leaks hilft dir vieleicht der nachfolgende Link weiter:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvc60/html/memleaks.asp
mfg JJ
-
Nein, das ist genau die Vorgehensweise, mit der ich nicht mal zuverlässig herausfinden kann, ob das Programm überhaupt leakt, weil der auch statische und globale Objekte dumpt.
Und da wird auch nicht angezeigt, wo die Objekte allokiert wurden.
Trotzdem danke.
-
In dem Artikel wird genau beschrieben wie man von der angezeigten Nummer zur Programmstelle mit dem Memory-Leak kommt. Ich habs auch schon in der Praxis verwendet.
Ein Allheilmittel ist es zugegebenermassen nicht. Zum Trost, auch teure Tools wie "Purify" oder "Bounds Checker" sind ebensowenig perfekt. Die "Debugging"-Bücher von John Robbins bzw Everett N. McKay geben viele nützliche Tips.mfg JJ
-
Also ich komm da immer nur auf den Code vom new Operator. Ich hab inzwischen auf Codework nen Source gefunden, der die Operatoren new und delete überlädt.
Der Vorteil ist, dass das ganze nur im Debug-Build überladen wird und man muss nichts includen, sondern nur die cpp dazulinken. Der Release-Build wird davon in keinster Weise beeinflusst.
Ab und zu meldet er zwar Sachen innerhalb von xstring, aber dafür findet er scheinbar alles andere zuverlässig und meldet auch keine falschen Sachen wie eine globale string-variable oder nen std::vector.
-
Die Allokationsnummer verweist sicherlich auf die Stelle wo der Speicher allokiert wird. Das sind überlicherweise malloc oder new. Von da aus kannst du jedoch uber den Aurufstack zurückverfolgen von wo aus deinem Code heraus die Allokation angefordert wurde. Das heisst, über _crtBreakAlloc solltest auf deinen Code zurückschliessen können.
mfg JJ
-
Hab das ganze mal ausprobiert:
#define _CRTDBG_MAP_ALLOC
funktioniert bei mir nicht zuverlässig, es wird also nicht immer die Datei + Zeilennummer angezeigt.
Malloc und new findet er in meinen kleinen Testprogramm.
Was aber ist mit BSTR wenn man ::SysAllocFree() vergißt. Oder was ist, wenn man ein Variant nicht mehr frei gibt?
-
Oder ne globale String-Variable. Das ist ja das Problem. :p
-
Hi,
gegen das zweite Problem kannst du was tun:
#define CRTDBG_MAP_ALLOC #include <crtdbg.h> // Allererster (!) Aufruf im Programm, bevor irgendwas allokiert wird! _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
Und den Aufruf am Ende raus (der geschieht jetzt automatisch, nachdem wirklich alles freigegeben wurde, auch statische und globale Instanzen).
Dateiangaben oder Zeilennummer kriegst du aber auch damit nicht, sind aber auch meistens nicht notwendig, wenn man schrittweise entwickelt und immer wieder nachguckt und dann testweise auskommentiert.
ChrisM
-
dafür benutzt man ja valgrind und co, weil die mit einem andere konzept arbeiten und nicht einfach new/delete ersetzen
-
dummi @ Experten-Runde
Sind globale std::strings böse?
Und wie kann man bei nem std::vector nen memleak bekommen? (_ohne_ grobe Fahrlässigkeit?)
-
Hi,
einige STL-Container beinhalten statische/globale Variablen.
ChrisM
-
Man kriegt ja durch std::vector kein Memory-Leak, aber die Funktion zum dumpen denkt das.
-
wenn man coden kann macht man auch keine memory leaks!
-
Ganz meiner Meinung. Ich hab durch die Tests auch festgestellt, dass mein Programm nicht leakt.