Kein Memory Leak, obwohl [] beim delete fehlen?
-
Hallo zusammen,
ein Kollege berichtete mir letztens, dass er ein SW-Projekt übernommen hat, in dem anstatt
delete []fälschlicher Weise immer nur das "einfache"
deleteverwendet wurde, obwohl der Speicher mit
new []alloziert wurde.
Aber er habe, merkwürdiger Weise, trotzdem keinen Memory Leak in dem Projekt gehabt. Auch im Taskmanager konnte er keinen Anstieg des Speichers feststellen.Das gleiche hatte auch schon viel früher, ein anderer Kollege behauptet, der jedoch aus Unwissenheit die falsche delete Anweisung (ohne []) verwendet hatte.
Nun habe ich das Ganze mal nachgestellt.
In einer Schleife habe ich dynamisch Speicher alloziertfor (int i = 0; i < 10000; i++) { long* plArray = new long [1000]; delete plArray; //delete [] plArray; }Wende ich keines der delete Anweisungen an, dann steigt der Speicher an.
Wende ich die falsche delete Anweisung andelete plArrayso verhält sich der benötigte Speicher genauso wie bei der korrekten delete Anweisung
delete [] plArray;Die ganzen Entwicklungen laufen dabei unter dem VC++ 2008, eventuell z.T. auch noch unter dem VC++ 2005 (das weiß ich aber nicht sicher).
Wie kommt es und seit welcher Version des Studios, wird die fehlerhafte delete Anweisung dort in irgendeiner Weise abgefangen?
Meinen Test habe ich sowohl in der Debug, als in der Release Version durchgeführt. Dabei gab es kein abweichendes Verhalten.
Danke für Infos und Tipps im Voraus.
-
Dabei gab es kein abweichendes Verhalten.
Mit welchen Mitteln hast du das Verhalten untersucht, der Taskmanager ist eher ungeeignet dafuer. Auch ist der Vorgang recht schnell und die Schleife kann vom Compiler durchaus wegoptimiert werden.
-
Ich hatte noch den Index der Schleife ausgegeben und ein Sleep(100) eingebaut, um das Verhalten im Taskmanager besser beobachten zu können.
Wie gesagt, ohne irgendeine der delete Anweisungen wächst der Speicher entsprechend an. Mit der falschen delete Anweisung wächst er gar nicht an, obwohl ja eigentlich nur der Speicher des ersten Elementes freigegeben werden sollte.
Der benötitge Speicher verhält sich genauso wie bei der korrekten delete [] Anfweisung.Welche Mittel sind denn Deiner Meinung nach dazu geeignet das Verhalten zu beobachten und zu untersuchen?
-
Naja, mit Leaktool. Wenn aber new/delete auf Basis von z.B. malloc/free implementiert sind, dann braucht es kein []. Jedoch kann es dann zu Problemen fuehren, falls komplexere Objekte benutzt werden. Dort wird dann der entsprechende Konstruktor nur einmal (vielleicht) aufgerufen. Das kannst du ja gern mal testen.
-
Den ersten Treffer, den ich jetzt mit LeakTool bei Google hatte, betraf nur Javaprogramme.
Kannst Du mir zu dem Tool eine genauere Angabe machen? Danke.Das mit den komplexeren Objekten werde ich demnächst mal austesten und davon berichten.
Mich hatte es immer gewundert, wieso ich, obwohl ich die Funktion
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );nutze, bei der delete Anweisung ohne [], keine Dumping Objects mehr ausgegeben wurde.
Ich hatte das darauf zurückgeführt, dass sobald dass erste Element, des zusammenhängenden Blocks, freigegeben wird, ein entsprechender Verweis fehlt und daher keine Ausgabe folgt, obwohl ein Speicherleck vorhanden ist.
Aber im Detail fehlt mir dazu das Hintergrundwissen.
-
Bei einem Build-In Typ passiert nix. Der Unterschied macht sich erst bei Klassen bemerkbar, welche selber dynamische Ressourcen besitzen. delete[] sorgt dafür, dass bei einem Feld von Objekten für jedes Objekt im Feld auch der Destruktor aufgerufen wird, was delete ohne [] nicht tut.