Destructor wird aufgerufen, speicher wird trotzdem nicht freigegeben, was ist da los ?
-
Bist du dir sicher, dass der Destruktor auch alles sauber aufräumt?
Ohne Code können wir leider nicht viel dazu sagen...
-
Euch ist schon klar, dass new/delete den Speicher nicht jedes mal vom Betriebssystem holen, sondern einen Pool haben, das heißt, dass deine Laufzeitumgebung den Speicher durchaus noch belegt haben kann falls du demnächst wieder ordentlich Speicher brauchst.
Und so lange es im System noch viel freien Speicher gibt hat diese auch keinen Grund ihn sofort wieder herzugeben.Benutze doch mal die Debugging Möglichkeiten deines Compilers, der zeigt dir normalerweise Leaks an.
Beim MSVC kannst du mal einen Blick in die debug.h werfen, dort gibt es auf jeden Fall eine entsprechende Methode.
-
Danke für die vielen Antworten.
@Pumuckl
Dachte dass das OS den Speicher gleich freigibt und man es im Taskmanager sieht, so war es auch bei meinem letzten Programm (war aber in C geschrieben).
Hört sich jedenfalls logisch an. Danke@Nexus
Der Destructor räumt alles auf, es gibt nämlich nur einen Zeiger, und der wird mit delete gelöscht. Ansonsten enthält ein Knoten keine Daten (bis auf einen Integer) die gelöscht werden müssen.@Tippgeber
Im System gibt es noch genügend Speicher, bei den Tests kam das Programm auf ca. 4000kb Speicher (stand im Taksmanager) beim starte hatte es nur 800 - 900kb.Kenne mich mit den Debugging Möglichkeiten von Compilern nicht aus
(benutze die gnu toolchain). Werd mir mal die debug.h von MSVC ansehen 
Wie überprüft ihr eigentlich eure Programme/Projekte auf Speicherleaks ?? (außer mit den debugging funktionen des Compilers)
Danke an alle für die Antworten !!
-
Gast4571248 schrieb:
Wie überprüft ihr eigentlich eure Programme/Projekte auf Speicherleaks ?? (außer mit den debugging funktionen des Compilers)
Möglichst RAII, smartpointer etc. benutzen und die Speicheranforderungen an möglichst wenig Stellen machen, so sind die Stellen wo überhaupt triviale Speicherlecks auftreten können nur wenige und meist gut manuell zu überprüfen. Komplizierter wirds bei Ringreferenzen, da muss man dann im Design drauf achten dass die nicht auftreten (können) bzw explizit aufgelöst werden.
-
die msvc runtime bietet dafür hilfreiche funktionen an.
-
Es gibt spezielle Speicherleck-Detektoren:
http://search.live.com/results.aspx?q=c%2B%2B+leak+detector
-
Was sind Ringreferenzen ? Hab gegooglt aber nichts gefunden.
Das was du gesagt hast sind Maßnahmen um sich vor Speicherleaks vorzubeugen, aber ich meinte eher, wenn ihr das Programm testen wollt, ob auch tatsächlich niregends ein Leak ist, wie macht ihr das.
Auf smartpointer und RAII auszuweichen ist zwar gut, aber da ich C++ noch nicht so gut kann, werd ich erst später darauf ausweichen.
Hab jetzt mal zu Testzwecken in C ein kleines Programm geschrieben welches nur mit malloc 1024.000 byte anfordert, und danach wieder freigibt, und auch hier sieht man im Taskmanager nur den Speicher ansteigen aber nicht fallen.
Also das Problem hat sich damit glaub ich erledigt, aber dazugelernt hat man wieder was

Sehr tolle/s Community/Forum

-
@letzten 2 Posts
Danke für die Links, hab geschrieben während ihr gepostet habt.
Was ich noch bemerkt habe:
Nachdem free() aufgerufen wird, sieht man im Taskmanager den Speicher um 4 kbyte kleiner werden
wenn ich free weglasse bleibt er so wie er ist (nach malloc).
-
pumuckl schrieb:
Wenn du im Programmcode den Speicher wieder freigibst, heißt das nicht dass der Speicher auf Betriebssystemebene sofort dem Porgramm wieder weggenommen wird. Das OS ist vermutlich umsichtig genug, um den eben benutzten Speicher erstmal weiterhin dem entsprechenden Prozess zuzuordnen, falls der nochmal für irgendwas Speicher anfordern sollte.
ich denken, du beschreibst den sachverhalt nicht richtig. das speichermanagment des prozesses arbeitet normalerweise unabhängig von dem des os und ruft dieses nur auf, wenn es neuen speicher haben will/welchen zurückgeben will. aber aus performancegründen nicht unbedingt auf basis von einzelnen freigaben/reservierungen. die modernen speicherlibs hand haben es dann so, dass sie speicherbereiche für kleine objekte in einer gewissenen menge an seiten ablegen. die menge kann wachsen, wird aber nie kleiner, da der verwaltungsaufwand sich im normalfall schlicht nicht lohnt. lediglich größere speicherbereiche werden tatsächlich an das system wieder zurückgegeben. das ist zumindest die funktionweis auf den unixoiden systemen, die ich kenne. im klassischen unix wurde sogar vollständig darauf verzichtet, speicher an das system zurückzugeben.
-
Gast23582538 schrieb:
Was sind Ringreferenzen ? Hab gegooglt aber nichts gefunden.
Wenn du über einen Smartpointer ein Objekt referenzierst, wird er das Objekt zerstören, sobald er selber zerstört wird (bzw. sobald der letzte smart pointer zerstört wird der das Objekt referenziert), du musst also nicht explizit delete aufrufen oder dich anderweitig um die Zerstörung des Objektes kümmern. So kannst du z.B. einen Baum aufbauen und nur das root-objekt halten, sobald du es zerstörst wird automatisch alles was daran hängt zerstört.
Anders ist das, wenn z.B Objekt A eine Referenz auf B hält, B wiederum auf C udn C auf A. Wenn nicht eins der Objekte explizit zerstört wird gibts immer ein anderes Objekt, was darauf eine Referenz hält und die Objekte bleiben im Speicher, selbst wenns von außerhalb des Ringes keine Referenzen mehr darauf gibt. Da solche Ringe zu sehr komplizierten Gebilden anwachsen können, kann es schwierig sein, solche unabhängigen Gebilde zu erkennen und zu zerstören. Sprachen mit Garbage-Collectoren (z.B. Java) können mit sowas Probleme bekommen, zumal dem programmierer dort die Problematik tendenziell weniger bewusst ist, da er sich normalerweise garnicht um Speicherverwaltung kümmern braucht (oder zumindest viel weniger als in C++)
-
Danke, tolle Erklärung !
Habe jetzt mein Programm mit einem memory leak detector getestet, kein Fehler gefunden
