none
Speicherleck nach delete eines Array-Zeigers RRS feed

  • Frage

  • Mal eine kurze Frage zu einem Stueckchen Code das sich mir nicht ganz erschliesst

     

    HANDLE Testarr;

    Testarr = new HANDLE[5];

    ... mach was

     

    delete Testarr;

    was ist daran falsch bzw. wie wird der delete richtig gemacht. Ich habe den dumpfen Verdacht das bei diesem Konstrukt ein Speicherleck bleibt oder liege ich da falsch ?

    Mittwoch, 2. März 2011 16:58

Antworten

  • Mich würde aber nochmal interressieren wie es denn mit dem Debugger möglich ist Speicherlecks aufzuspüren ? Ich kenn das nur noch von VS 6 aber da war das sehr rudimentär, wir sind deshalb schon vor einigen Jahren zu Boundschecker gewechselt.
    Hat sich das inzwischen verbessert ?

    Dir grundsätzliche Technik ist in VS-2010 immer noch gleich. In der CRT wird ein anderer Allocator verwendet und bei Bedarf new gegen DEBUG_NEW getauscht.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Donnerstag, 3. März 2011 07:20
    Moderator

Alle Antworten

  • Am 02.03.2011 17:58, schrieb Jörg Tiedemann:


    HANDLETestarr;
    Testarr =newHANDLE[5];
    deleteTestarr;

    was ist daran falsch bzw. wie wird der delete richtig gemacht. Ich habe den
    dumpfen Verdacht das bei diesem Konstrukt ein Speicherleck bleibt oder liege
    ich da falsch ?

    Ob Speicherlecks bleiben, kann dir der Debugger genau sagen. Richtig wäre

    HANDLE *Testarr;
    Testarr = new HANDLE[5];
    .
    .
    delete Testarr;

    mal ganz ganz abgesehen davon, dass ich keinen Sinn darin sehe, sowas dynamisch zu allokieren.

    Hajü

    Mittwoch, 2. März 2011 17:34
  • HANDLE *Testarr;
    Testarr = new HANDLE[5];
    .
    .
    delete Testarr;

    Sorry für die Korektur aber korrekt ist bei einem Array immer nur:
    delete [] Testarr;


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Mittwoch, 2. März 2011 18:37
    Moderator
  • Sorry für die Korektur aber korrekt ist bei einem Array immer nur:
    delete [] Testarr;

    Ja, so steht es in irgendwelchen Büchern, warum eigentlich? Das ist wohl mehr reine Formsache. Ein eindimensionales Array ist doch auch nichts anderes als ein Pointer. Ich hab's gestestet wie ich's geschrieben habe und es läuft einwandfrei durch, ohne Memory leaks. Deine Variante überigens auch.

    Hajü

    Mittwoch, 2. März 2011 22:53
  • > Ja, so steht es in irgendwelchen Büchern, warum eigentlich? Das ist wohl mehr reine Formsache. Ein eindimensionales Array ist doch auch nichts anderes als ein Pointer. Ich hab's gestestet wie ich's geschrieben habe und es läuft einwandfrei durch, ohne Memory leaks. Deine Variante überigens auch.

    Für PODs und einfache Datenstrukturen ist hier nichts anders.
    Wenn es sich aber um einen Array von Objekten handelt, dann garantiert nur delete [], das alle Destruktoren aufgerufen werden.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Donnerstag, 3. März 2011 06:48
    Moderator
  • Ja denn wenn du nur delete irgendwas ausführst wird nur die Zuweisung vom 1. Element gelöscht. Alle anderen bleiben bestehen. wenn du delete [] irgendwas ausfphrst dann weiss der compiler es handelt sich um ein array.
    Donnerstag, 3. März 2011 06:57
  • Hallo

    Danke für die Antwort
    der delete [] führt auf jeden Fall zu Lösung.
    Ich verwendet Boundschecker von Devpartner zur Analyse von Speicherlecks und der hat mir bei
    delete Testarr;
    einen Allocation Conflict gemeldet und sagt mit bei
    delete [] Testarr;
    das alles ok ist. Insofern war delete [] genau das wonach ich gesucht habe.
    In dem Beispiel wird natürlich
    Testarr HANDLE [5];
    in Wirklichkeit dynamisch erzeugt da es ansonsten ja wenig Sinn macht da liegt Hajü völlig richtig.
    Mich würde aber nochmal interressieren wie es denn mit dem Debugger möglich ist Speicherlecks aufzuspüren ? Ich kenn das nur noch von VS 6 aber da war das sehr rudimentär, wir sind deshalb schon vor einigen Jahren zu Boundschecker gewechselt.
    Hat sich das inzwischen verbessert ?

    Donnerstag, 3. März 2011 07:17
  • Mich würde aber nochmal interressieren wie es denn mit dem Debugger möglich ist Speicherlecks aufzuspüren ? Ich kenn das nur noch von VS 6 aber da war das sehr rudimentär, wir sind deshalb schon vor einigen Jahren zu Boundschecker gewechselt.
    Hat sich das inzwischen verbessert ?

    Dir grundsätzliche Technik ist in VS-2010 immer noch gleich. In der CRT wird ein anderer Allocator verwendet und bei Bedarf new gegen DEBUG_NEW getauscht.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Donnerstag, 3. März 2011 07:20
    Moderator
  • Am 03.03.2011 07:48, schrieb Martin Richter [MVP]:

    Für PODs und einfache Datenstrukturen ist hier nichts anders.
    Wenn es sich aber um einen Array von Objekten handelt, dann garantiert nur
    delete [], das alle Destruktoren aufgerufen werden.

    Das stimmt natürlich. Wenn sich irgendwann im Entwicklungszyklus der Software mal der Datentyp hin zu einer Klasse ändert und niemand mehr dran denkt, hat man mit einfachem delete ein Problem. Hatte ich gar nicht mehr dran gedacht. Ich hab's mal probiert:

    CString *Testarr;
    Testarr = new CString[5];
    delete Testarr;

    führt zu:
    [message]
    Windows hat einen Haltepunkt in Schrott.exe ausgelöst.

    Dies kann auf eine Beschädigung des Heaps zurückzuführen sein, die auf ein Problem in Schrott.exe oder in einer der geladenen DLLs hinweist.

    Dies kann auch darauf zurückzuführen sein, dass der Benutzer F12 drückt, während Schrott.exe den Fokus hat.

    Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.
    [/message]

    Aber immerhin merkts's der Debugger noch.


    Hajü

    Donnerstag, 3. März 2011 11:05