new und delete bei vector<object*> - kurze Frage



  • Guten Morgen :),

    in dem Buch "C++ Primer" bin ich beim bewältigen der einzelnen Übungsaufgaben auf eine Sache gestoßen, bei der ich wohl etwas klärungsbedarf habe. Hier mal ein, auf die wichtigsten Bestandtteile gekürzter, Beispielcode:

    class Checkoutrecord {
    public:
    	typedef std::vector< std::pair<std::string, std::string>* > w_list;
    	void add_wlist(const std::string&, const std::string&);
        ~Checkoutrecord();	
        /* ... */
    private:
    	std::vector< std::pair<std::string, std::string>* > wait_list;
        /* ... */
    };
    
    // Fügt Name eines Kunden zur "Warteliste" hinzu
    void Checkoutrecord::add_wlist(const std::string &first, const std::string &second)
    {
    	wait_list.push_back(new std::pair<std::string, std::string>(std::make_pair(first, second)));
    	return;
    }
    
    // Destruktor
    Checkoutrecord::~Checkoutrecord()
    {
    	w_list::size_type i = 0;
    	while (i != wait_list.size())
    		delete wait_list[i++];
    }
    

    Im Buch vorgegeben war das Datenelement wait_list , der Rest ist von mir. Aber es geht mir nicht so sehr um die Aufgabe in dem Buch, sondern mich interessiert viel mehr was im Destruktor der Klasse passiert.

    Checkoutrecord::~Checkoutrecord()
    {
    	w_list::size_type i = 0;
    	while (i != wait_list.size())
    		delete wait_list[i++];
    }
    

    Ich bin beim Schreiben des Destruktors davon ausgegangen, dass durch das Freigeben des Speichers mit delete auch die entsprechenden Elemente des Vektors wait_list mitgelöscht werden, aber stimmt das denn überhaupt? Oder habe ich nach dem Aufruf des Destruktors nur einen Vektor dessen Elemente ungültige Zeiger sind?



  • dein Vector

    std::vector< std::pair<std::string, std::string>* > wait_list;
    

    enhält ja zeiger auf objecte des typs

    std::pair<std::string, std::string>
    

    hier erzeugst du ein objekt des typs mit new und merkst dir diese allokierten speicher über den pointer welchen du im vector speichert.

    wait_list.push_back(new std::pair<std::string, std::string>(std::make_pair(first, second)));
    

    im destruktor werden alle Elemente (pointer) deines vector durchlaufen, und alle speicehrbereich auf die die pointer zeigen mit delete gelöscht

    w_list::size_type i = 0;
        while (i != wait_list.size())
            delete wait_list[i++];
    


  • Das heißt das du nach dem Aufruf des Destruktor bzw nach Aufruf der Schleife da drin eine wait_list voller ungültiger Pointer hast. Was aber ja kein Problem ist, da das Objekt dann eh gelöscht wird.



  • Und nun.... die Antwort auf die Frage:

    Am Ende des Destruktors hast Du tatsächlich einen Vector mit lauter ungültigen Zeigern. Das ist aber nicht tragisch, da dieser Vector nach Ablauf des Destruktors sowieso freigegeben wird, da der Destruktor ja gerade das Objekt freigibt, welches den Vector enthält. Und ein Vector gibt bei seiner Freigabe auch immer alle seine Elemente frei (Achtung: Nicht jedoch das, worauf seine Elemente zeigen, wenn es denn Zeiger sind, aber das machst Du ja selbst).

    (EDIT: Bei Erstellung des Eingangssatzes war das Posting von Fellhuhn noch nicht sichtbar)



  • Hui, die Antworten kamen aber echt schnell und haben mich zudem vollends aufgeklärt. Vielen Dank an alle :).


Anmelden zum Antworten