DynamicArray, unklare Aussagen zum Löschen



  • Hallo,
    benötige endgültige Klärung zu DynamicArray. Hier im Forum gibt es z.T. widersprüchliche Aussagen. 👍 👎

    in der BCB-Hilfe steht

    Um ein dynamisches Array freizugeben, setzen Sie einfach seine Größe auf 0:

    arrayOfInt.Length = 0;

    Dies verführt dazu zu glauben, dass auch ein Array, das mit dynamisch erzeugten Variablen gefüllt ist, gelöscht werden würde.
    Wenn ich das aber richtig verstehe bezieht sich das Löschen nur auf den Zeiger auf das DynamicArray an sich. Schlauerweise findet sich kein weiterer Hinweis zu einem solchen Fall-Beispiel mit dyn. Elementen in der BCB-Hilfe.

    Das heißt mit anderen Worten, wenn ich in diesem DynamicArray diverse Elemente mit new generiert habe, muß ich genau diese vor dem Ende von DynamicArray sehr wohl mit delete gelöscht haben.
    Ansonsten würden Datenleichen zurückbleiben. (Ausnahme: mit new objekt(this) erzeugte Instanzen oder statische Elemente)

    Kann das jemand so bestätigen?



  • DynamicArray <int*> pinteger;
    pinteger.Length ++;
    pinteger[0] = new int;
    

    In diesem Fall musst du dich selber um das löschen kümmern.

    DynamicArray <TForm*> pForm;
    pForm.Length ++;
    pForm[0] = new TForm(Application);
    

    In dem Fall wird dir das abgenommen.



  • Hallo

    thunderbol4 schrieb:

    Hallo,
    benötige endgültige Klärung zu DynamicArray. Hier im Forum gibt es z.T. widersprüchliche Aussagen. 👍 👎

    So? Da möchte ich aber gerne mal einen Beispiel-Thread sehen.
    Die meisten Stammleser hier kennen sehr wohl die Grundlagen von C++.

    Das Prinzip von DynamicArray (und auch std::vector und allen anderen ähnlichen Containern) ist doch ganz klar. Alle kümmern sich um die Speicherverwaltung für ihre Elemente. Wenn die Elemente aber Pointer sind, werden eben nur die Pointer gelöscht, nicht aber die Instanzen hinter den Pointern.

    bis bald
    akari



  • Guten Morgen @akari, @flocke

    Danke für Eure Hinweise und Bestätigung zu DynamicArray
    Akari schrieb

    So? Da möchte ich aber gerne mal einen Beispiel-Thread sehen.

    Au Backe, wo hab' ich den Thread bloß wieder hingelegt? 😕 😃 .
    Lieber @akari, Du hast recht, da habe ich mich etwas weit zum Fenster hinausgelehnt. Beim genaueren Durchstöbern im Forum finde ich tatsächlich keinen Hinweis, dass es 'mal so oder so heißt.

    Lediglich dieser Thread ist mir in Erinnerung geblieben.
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-101318-and-highlight-is-.html

    BigNeal schrieb

    soweit ich die bcb-hilfe verstanden habe, hat sich das delete erledigt..
    BCB-Hilfe schrieb:
    Um ein dynamisches Array freizugeben, setzen Sie einfach seine Größe auf 0:

    arrayOfInt.Length = 0;

    Fairer Weise hier nochmals der gesamte Zusammenhang von @BigNeal

    ich war gestern gerade auf dem heimweg und ich hatte das auch noch nie gemacht..

    😃 man höre und staune, sorry da konnte ich mich gerade nicht beherrschen 😉 😃

    jetzt aber wieder ernsthaft
    BigNeal schrieb

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
       btn2D.set_length(1);    //1. Dimension grösse auf 1 setzen
    
       //btn2D.Low = 0;
       for (int x=0;x<6;x++)
       {
          btn2D.Length++;     // grösse für 1. Dimension vergrössern
    
         // btn2D[x].set_length(10);   //grösser der 2. Dimension für btn2D[x] auf 10 setzen
          for (int y=0;y<6;y++)
          {
             //ShowMessage((String)x+"/"+(String)y);        // durchläufe kontrollieren
             btn2D[x].Length++;
             btn2D[x][y] = new TButton(this);
             btn2D[x][y]->Parent = Form1;
             btn2D[x][y]->Caption = (String)x+"/"+(String)y;
             btn2D[x][y]->Height = 20;
             btn2D[x][y]->Width = 30;
             btn2D[x][y]->Top = y*20;
             btn2D[x][y]->Left = x*30;
    
          }
       }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormDestroy(TObject *Sender)
    {
       btn2D.Length = 0;           // dynamisches Array freigeben
    }
    

    soweit ich die bcb-hilfe verstanden habe, hat sich das delete erledigt..
    BCB-Hilfe schrieb:
    Um ein dynamisches Array freizugeben, setzen Sie einfach seine Größe auf 0:

    arrayOfInt.Length = 0;

    Bei genauem Durchlesen ist diese Behauptung von @BigNeal aber für diesen gezeigten Fall korrekt.

    @akari
    Leider besteht ab und zu Unsicherheit, was jetzt richtig ist.
    Schließlich ist das ja hier kein Lehrbuch, in man alles glauben kann, was darin steht, sondern eben ein Forum, in dem jeder zuerst mal seine eigene Meinung/Lösungsvorschlag äußern darf. Nicht jeder Fehler, der dabei entsteht und hier reingeschrieben wird, wird auch ausgemerzt.
    Sicherlich versuchen Moderatoren/Stammschreiber/Spezialisten, wer auch immer das gröbste zu verbessern. Bei dem Umfang und dem komplexen Thema C++ ist das, denke ich, nicht möglich. Da wird immer was durchschlupfen! 😉



  • Ich kann nur sagen verzichte lieber auf DynamicArray es sei denn du brauchst es unbedingt als Schnittstelle zu Pascal-Komponenten.
    In C++ nimmt man statt dessen vector welches meiner Meinung nach einen klareren Syntax hat. Weiterhin findest du dazu viel mehr und bessere Erläuterungen, kannst die Standard-Algorithmen nutzen und besitzt eine gewisse Kompatibilität zu den einfachen Arrays.



  • Und doch ist das Beispiel von BigNeal korrekt und führt zu keinem Speicherleck.
    Da die Buttons mit "this" (=Form1) als Eigentümer (Owner) erzeugt werden, werden diese auch beim Löschen des Formulars automatisch mitgelöscht.

    Nur die Zeile nach dem Konstruktor sollte man umschreiben:

    btn2D[x][y] = new TButton(this); // TForm-Instanz als Eigentümer
    btn2D[x][y]->Parent = this; // statt Form1
    

    Man sollte innerhalb von Klassenmethoden niemals auf globale Variablen zugreifen (wie z.B. Form1), sondern immer auf die eigene Klasseninstanz (this).
    Leider sehe ich diesen Fehler hier im Forum (gerade bei den Anfängern) recht häufig.


Anmelden zum Antworten