PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Speicherlecks aufstöbern


crusader4
2007-11-15, 21:30:57
Hallo Forum!
In Sachen Programmierung bin ich ein Autodidakt, in letzter Zeit habe ich mich mir für ein Projekt C++ angeeignet. Nun sitze ich an einem Programm, in welchem häufig Objekte verschiedenen Typs angelegt und zerstört werden. Dabei werden die Objekte meist in einem Thread erstellt, in einen anderen Thread transferiert, bearbeitet und dort gelöscht (oder in einen weiteren Thread transferiert, der dann als Senke dient). Alle Methoden übergeben Zeiger auf die Objekte.

Nun soll diese Software nicht nur zwei Stunden, sondern Monate bis Jahre laufen (wie die Vorgängerversion das schon tat, ich habe aber sehr viele Veränderungen vorgenommen), so daß ich möglichst viele Speicherlecks entdecken muß. Bisher habe ich dazu in den Konstruktoren und Destruktoren der einzelnen Objektklassen eine Ausgabe eingebaut, die mir in eine Logdatei die Entstehung und Zerstörung eines Objekts mitschreibt. Damit kann ich zumindest prüfen, ob alle entstehenden Objekte auch entfernt werden.

Nun habe ich einige Fragen, die sich mit Abstürzen des Programms beschäftigen:
Gibt es eine Möglichkeit, die Gültigkeit eines Pointers zu testen? Bei einem delete auf ein Objekt wird selbiges zwar zerstört, aber der Zeiger auf das Objekt enthält immer noch den Wert. Hintergrund ist, das ich verhindern will, das ein Objekt mehrfach gelöscht wird. Eine Maßnahme die ich getroffen habe, ist Objekte nur an wenigen, zentralen Stellen zu löschen, um die Nachprüfbarkeit zu verbessern.

Weiterhin wollte ich den Zeigern nach einem delete den Wert NULL zuweisen, allerdings funktioniert folgendes nicht (wohl aufgrund der Parameterübergabe an die Funktion über den Stack):

#include <stdio.h>
#include "myclass.h"

void destruct(Cmyclass *p)
{
delete p;
p=NULL;
}

int main(void)
{
Cmyclass *myclass=new Cmyclass();
// do something
destruct(myclass);
printf("\Cmyclass-pointer=%p",myclass);
return 0;
}


Die Ausschrift ist nicht "Cmyclass-pointer=(nil)", sondern halt der Wert des Pointers. Gibt es eine Möglichkeit, die gewünschte Funktionalität zu implementieren? Das würde mir das Leben einfacher machen, weil ich dann in allen Funktionen einfach nur auf ein NULL-sein des Pointers prüfen müßte, bevor ich was damit anstelle.

Welche weiteren allgemeinen Tipps habt ihr für meine Vorhaben, um die Verfolgung zumindest zu erleichtern? Mir ist bewußt, das bei Programmen mit dynamischer Speicherverwaltung, und dann auch noch mit mehreren Threads viel Handarbeit gefragt ist und ich mir wohl den Weg jedes Objekttyps noch einmal ganz genau anschauen muß.

Im Voraus vielen Dank!

Grüße, Crusader

P.S.: Falls die Fragen zu trivial sind, kurz zur Erklärung: Ich bin zu diesem Projekt eher zufällig gekommen, und man ist auch mit mir zufrieden. Allerdings bin ich kein Informatiker und habe mir C++ nur durch den vorherigen Softwarebestand und einem Referenzbuch der Sprachelemente angeeignet. Daher sind meine theoretischen Kenntnisse nicht vorhanden, ich kenne nur die praktische Seite. Daher bin ich dankbar für Tipps, Howtos und Tutorials, weil ich mir Informationen recht schnell erarbeiten kann. Grundlagen der Computertechnik kenne ich auch, von Hause aus bin ich Elektrotechniker.

del_4901
2007-11-15, 21:43:10
Zu deinem Problem, übergib den Zeiger über eine Referenz, sonnst setzt du nur die Kopie auf NULL.

Ja man kann überprüfen ob was gelöscht wurde, indem man sich einen eigenen Speichermanager schreibt, und dann new & delete überläd. Man kann via SmartPointers und Referencecounting auch automatisch löschen lassen. (Geht häufig aber nicht Immer)

Wenn du Objekte in unterschiedlichen Threads erzeugst, wie sie gelöscht werden, ist das ein schlechtes Design.

malte.c
2007-11-15, 22:14:19
Nun soll diese Software nicht nur zwei Stunden, sondern Monate bis Jahre laufen (...), so daß ich möglichst viele Speicherlecks entdecken muß.

http://valgrind.org/
http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

Coda
2007-11-15, 22:18:18
http://www.paulnettle.com/pub/FluidStudios/MemoryManagers/Fluid_Studios_Memory_Manager.zip

Asmodeus
2007-11-16, 07:55:13
auch noch eine Möglichkeit, für einen ersten schnellen Überblick über Speicherlecks: http://www.codeproject.com/debug/Memory_leak_finder.asp?df=100&forumid=30832&exp=0&select=934818

Gruß, Carsten.

Gast
2007-11-16, 08:47:33
http://www.paulnettle.com/pub/FluidStudios/MemoryManagers/Fluid_Studios_Memory_Manager.zip Das Ding ist Klasse, hatte es bei einem früheren Projekt schonmal ausprobiert und es funktioniert sehr gut. Findet oft nochmal irgendwo was..

Gast
2007-11-16, 08:48:08
Wird es Valgrind eigentlich mal für Windows geben?

Coda
2007-11-16, 12:35:09
Eher nicht. Aber das Ding das ich verlinkt habe findet zumindest Speicherlecks genauso zuverlässig und man sieht sogar genau wo und wieviel.

Wenn man das mit dem Bound-Checking von Visual C++ 2005 kombiniert hat man eigentlich ein fast so mächtiges Werkzeug wie valgrind.

crusader4
2007-11-16, 16:44:47
Hallo!
Danke für die Hinweise, doch leider hatte ich einen wichtigen Fakt vergessen zu erwähnen. Entwickelt wird unter Linux mit Eclipse, das Zielsystem ist ein ARM und der Compiler ist arm-linux-gcc 2.95.3.

Daher sind einige Software-Hinweise leider nicht anwendbar. Das von Coda genannte System werde ich mir mal genauer anschauen, das scheint ja Betriebssystem- und plattformunabhängig zu sein. Ich hatte aber leider nur Zeit für einen kurzen Blick.

@AlphaTier: Das Design der Software habe ich mir nicht ausgedacht, das steht schon. Das zu ändern würde sehr viel Zeit kosten, und die habe ich in dem Projekt nicht.


Grüße, Crusader

Gast
2007-11-21, 10:12:09
Eher nicht. Aber das Ding das ich verlinkt habe findet zumindest Speicherlecks genauso zuverlässig und man sieht sogar genau wo und wieviel. Ist jeder Eintrag sicher ein Speicherleck?

Kann man Qualität der Speicherlecks unterschieden? D.h. eine Stelle, wo mehrfach oder regelmäßig Speicher abgezogen wird gegenüber einer wo dies nur einmalig geschieht?

Wenn da nur Fragezeichen stehen, heißt dies, daß der Speicher irgendwo angefordert wurde, wo MMGR bisher nicht inkludiert wurde?

Gast
2007-12-06, 13:41:32
Das ist mal echt sinnvoll. Man soll das Gerät in jede cpp Datei inkludieren, Kann man das auch quasi global machen und in jede cpp Datei eine PreProc-Anweisung aufnehmen, die das ganze nach einem globalen Schalter akt/oder deaktiviert?

Coda
2007-12-06, 22:15:39
Ist jeder Eintrag sicher ein Speicherleck?
Nach meiner Erfahrung: Ja.

Kann man Qualität der Speicherlecks unterschieden? D.h. eine Stelle, wo mehrfach oder regelmäßig Speicher abgezogen wird gegenüber einer wo dies nur einmalig geschieht?
Kann man, wenn man mmgr.h einbindet, dann taucht die Stelle mehrfach auf.

Wenn da nur Fragezeichen stehen, heißt dies, daß der Speicher irgendwo angefordert wurde, wo MMGR bisher nicht inkludiert wurde?
Korrekt. Das ist das einzige was ein wenig nervig ist. Man muss schauen dass man das immer macht.

Übrigens habe ich durch das Tool auch gelernt Speicherlecks erst gar nicht zu einzubauen. Guter Trainer.

Gast
2007-12-07, 08:46:27
Bei einigen Projekten funktioniert das wunderbar, bei anderen habe ich aber auch Probleme...

Entweder kommt ein Compile Error der Form:
"error C2457: '__FUNCTION__': Ein vordefiniertes Makro kann nicht außerhalb eines Funktionsrumpfs vorkommen"

...oder es kommen unzählige Linker Errors, daß _malloc, _free, etc. schon in MSVCRTD.lib definiert sind. Kann man das Tool in einem oder beiden Fällen trotzdem dazu überreden mit dem Projekt zusammenzuarbeiten?

Gast
2008-02-13, 13:07:45
Diese mem-leak-check von valgrind klappt schon sehr gut, aber gibt es für valgrind ggf. auch eine aufgeräumte Gui? Oder ein Eclipse Plugin?

mekakic
2008-06-16, 13:00:03
valgrind
Wie spricht man das eigentlich aus? Englisch oder wie heißt dies im Deutschen?

Coda
2008-06-16, 18:49:26
http://valgrind.org/docs/manual/faq.html#faq.pronounce

mekakic
2008-06-17, 09:02:01
Danke!