Problem mit Löschen von Vektor-Elementen



  • Ich habe einen STL-Vektor, der mit verschiedenen Zeigern auf polymorphe Objekten gefüllt ist (also Instanzen verschiedener Klassen mit alle derselben Basisklasse). Wenn ich clear() aufrufe, dann sollen angeblich die Destruktoren der Elemente aufgerufen werden, bevor sie aus dem Vektor entfernt werden. Der Destruktor der Basisklasse ist außerdem virtual, also sollte auch immer der abgeleitete Destruktor mit aufgerufen werden. Trotzdem passiert das nicht, es wird weder der abgeleitete, noch der Basis-Destruktor aufgerufen. Erst wenn ich eine Schleife schreibe, die jedes Element manuell per delete löscht, werden auch die Destruktoren aufgerufen.

    Woran liegt denn das?



  • Es wird nicht der Destruktor der Elemente aufgerufen. Das musst du schon durch eine Schlaufe und delte/delete[] selber machen.
    -> Merke: Alles, was DU an Speicher anforderts, musst auch DU wieder freigeben. Das heisst für jedes new soll es auch ein delete in DEINEM Code geben.



  • Wenn in Deinem vector Objekte wären, würden auch die Destruktoren aufgerufen werden. Es sind aber Zeiger drin. Objekte, die durch Zeiger referenziert werden, musst Du explizit mit delete zerstören.



  • David Schneider schrieb:

    Wenn ich clear() aufrufe, dann sollen angeblich die Destruktoren der Elemente aufgerufen werden, bevor sie aus dem Vektor entfernt werden.

    Das wird auch getan, nur verwendest du Zeiger als Element, und die Zeiger (nicht die Elemente auf die gezeigt wird) werden aufgeräumt. Das ist auch ziemlich logisch, da es dem normalen C++ verhalten entspricht:

    int main()
    {
      {
        int a = 4;
      } // <-- hier wird a destruiert
      {
        int * a = new int(4);
      } // <-- hier wird a destruiert, nicht aber dass, auf das gezeigt wird!
    }
    

    Grundsätzlich gilt sonst das von drakon geschriebene, oder du verwendest Smartpointer (die sich beim Destruieren auch um die Speicherfreigabe kümmern)

    Dies könnte z.B. wie folgt aussehen:

    // statt
    std::vector<BaseClass*> basePtrList;
    // nehmen wir eines der folgenden (erfordert boost oder tr1)
    std::vector<std::tr1::shared_ptr<BaseClass> > tr1SmartPtrList;
    std::vector<boost::shared_ptr<BaseClass> > boostSmartPtrList;
    

    cu André



  • Ja, richtig. Wie dumm von mir...


Anmelden zum Antworten