new/delete und STL-Container



  • Hi,

    angenommen ich habe

    vector<myObject> myVector;
    

    wenn ich jetzt folgendes mache

    myVector.push_back(new myObject);
    

    kann ich dann

    delete myVector[0]; //bzw. myVector[1, 2, ..., x]
    

    machen oder entsteht dabei irgendwie ein Speicherleck?

    ciao



  • Wenn du ein vector<myObject*> hättest, dann ja.



  • Mit new lieferst Du einen Pointer zurück, daher wie vorgeschlagen:

    #include "xINT.h"
    #include <vector>
    using namespace std;
    
    int main()
    { 
      {
        vector<xINT*> myVector;
        myVector.push_back( new xINT );
        delete myVector[0]; 
      }
    }
    

    Ausgabe:
    00316410: ctor
    00316410: dtor

    Testklasse xINT zum Experimentieren siehe: http://www.henkessoft.de/C++/C++ Fortgeschrittene/C++_Fortgeschrittene.htm#2.2._Unsere_Testklasse_loggt_mit

    Es funktioniert also.



  • ⚠ Achtung ⚠
    Du löscht dabei nur das Objekt, der Zeiger bleibt im Vector, und zeigt ins Nirvana.
    Beim nächsten Zugriff kann es krachen.
    Der Zeiger muss noch aus dem Vector entfernt werden mit remove()..



  • ... was aber beim Vektor vorne extrem ineffektiv ist. Wenn du an beiden Enden schnell einfügen und entfernen willst nimm deque und mach es so:

    std::deque<bla*> myDeque;
    myDeque.push_back (new bla);
    delete myDeque.front ();
    myDeque.pop_front ();
    


  • Vielen Dank euch allen. Das ich den Container mit Pointern machen muss ist mir auch 20 minuten später eingefallen, aber da war ich schon im Bett^^.

    Ich muss aber zuerst den delete-operator benützen und anschließend das Element aus aus dem Container entfernen, stimmt's? Denn das Element ist ja dann nicht mehr drinnen und ich hätte ein Speicherleck.



  • std::vector<MyClass*> myVector;
    //...
    MyClass* temp = myVector[0];
    myVector.remove(temp); //Syntax? bin mir grad nicht sicher
    delete temp;
    

    So geht es auch. Der Speicher auf dem Heap ist völlig unabhängig von deinem Vektor.



  • blub2k6 schrieb:

    std::vector<MyClass*> myVector;
    //...
    MyClass* temp = myVector[0];
    myVector.remove(temp); //Syntax? bin mir grad nicht sicher
    delete temp;
    

    So geht es auch. Der Speicher auf dem Heap ist völlig unabhängig von deinem Vektor.

    Das wäre also eine Möglichkeit zuerst das Element zu entfernen und danach erst das Objekt zu löschen, richtig?
    Das widerspricht aber meinem ürsprünglichen Plan eben genau diese temporären Pointer zu vermeiden.

    Beispiel: Anstatt

    vector<myClass*> myVector;
    myClass *temp = new myClass,
    myVector.push_back(temp);
    //... temp auf andere Objekte zeigen lassen ...
    temp = myVector[0];
    myVector.remove(temp);
    delete temp;
    

    zu schreiben, wollte ich das ganze verkürzen und nur

    vector<myClass*> myVector;
    myVector.push_back(new myClass);
    //...
    delete myVector[0];
    myVector.remove(myVector[0]);
    

    schreiben.

    Ich war mir aber dabei nicht sicher ob das geht und ob da nicht doch irgendwelche Speicherlecks entstehen. Aber jetzt ist glaube ich alles klar. Danke!





  • Könntest du mir einmal bitte ein Beispiel schreiben wie auto_ptr mein Anliegen vereinfachen würden? Als Containerelement sind sie ja ungeeignet wie ich bei dir gelesen habe. Also kommen sie nur als Ersatz für die temporären Pointer infrage.

    Meinst du etwa so in der Art?

    std::vector<myClass*> myVector;
    myVector.push_back(new myClass);
    //...
    auto_ptr<myClass> pointer(myVector[0]);
    myVector.remove(pointer);
    

    pointer würde dann automatisch den oben mit new angeforderten Speicher wieder freigeben, stimmt's?

    PS: In den Tutorials über new/delete steht immer, dass "gute" Betriebssysteme den Speicher nach Beendigung des Programmes von selbst wieder freigeben. Gehören die gängigen Betriebssysteme Windows, Mac, Linux, Unix, etc. denn zu den "guten" Betriebssystemen? Bei Windows weiß man ja nie...



  • Frager schrieb:

    Könntest du mir einmal bitte ein Beispiel schreiben wie auto_ptr mein Anliegen vereinfachen würden? Als Containerelement sind sie ja ungeeignet wie ich bei dir gelesen habe. Also kommen sie nur als Ersatz für die temporären Pointer infrage.

    Ja das stimmt, als Containerelement sind sie ungeeignet. Du könntest dir boost::ptr_vector angucken, das vereinfacht es wirklich.

    PS: In den Tutorials über new/delete steht immer, dass "gute" Betriebssysteme den Speicher nach Beendigung des Programmes von selbst wieder freigeben. Gehören die gängigen Betriebssysteme Windows, Mac, Linux, Unix, etc. denn zu den "guten" Betriebssystemen? Bei Windows weiß man ja nie...

    Gewöhn dir am besten gar nicht erst an, dich darauf zu verlassen. Was nämlich wenn dein Programm nicht beendet wird?

    mfg.



  • Aber nach einem Neustart ist der Speicher doch auf jeden Fall wieder freigegeben, oder?


Anmelden zum Antworten