Vector clear() löscht Elemente nicht!
-
std::vector<int> vecTest;
//In Konstruktor, speicherplatz für 10 Elemente reservieren und mit 0 belegen
vecTest.resize(10, 0)//Werte in vector speichern
vecTest.at(1) = 112;
vecTest.at(2) = 123;
vecTest.at(3) = 124;//Hier alle Elemente löschen
vecTest.clear();Mein Vector hat nachwievor alle Elemente, d.h.
vecTest.at(i) ist immer noch 112 usw.Warum löscht clear() meine Elemente nicht. Was mache ich falsch?
Liegt es an resize? Für meine Anwendung muss ich aber vorher Speicherplatz reservieren.Danke für Hilfe
-
also die diskussion kam vor eingier zeit glaube ich mal auf
da hieß es, dass vector bei clear nur die size auf 0 setzt. wie der das intern handhabt und wann der den speicher löscht ist dem seine sache
-
Der Standard besagt, dass beim Aufruf von
clear()alle Elemente destruiert und freigegeben werden. Daat()geprüfter Zugriff bietet, läuft definitiv irgendwas total schief... (beioperator[]()hätte ich es noch verstanden.)
-
EOutOfResources schrieb:
Der Standard besagt, dass beim Aufruf von
clear()alle Elemente destruiert und freigegeben werden.Zerstört ja, aber der Speicher bleibt belegt.
EOutOfResources schrieb:
Da
at()geprüfter Zugriff bietet, läuft definitiv irgendwas total schief...Richtig, da sollte eine Exception fliegen.
goldenBoy, hast du ein vollständiges kompilierbares Codebeispiel mit einer Ausgabe, das dein Problem reproduziert? Benutze zur Darstellung bitte [cpp]-Tags (erste weisse Schaltfläche).
-
Nexus schrieb:
Zerstört ja, aber der Speicher bleibt belegt.
Standard 23.2.4.4 §3 schrieb:
iterator erase ( iterator position );
iterator erase ( iterator first , iterator last );
Effects: Invalidates iterators and references at or after the point of the erase
Verstehe ich den Standard falsch? Iteratoren sollten doch noch gültig sein, wenn nichts freigegeben wird.
-
EOutOfResources schrieb:
Nexus schrieb:
Zerstört ja, aber der Speicher bleibt belegt.
Standard 23.2.4.4 §3 schrieb:
iterator erase ( iterator position );
iterator erase ( iterator first , iterator last );
Effects: Invalidates iterators and references at or after the point of the erase
Verstehe ich den Standard falsch? Iteratoren sollten doch noch gültig sein, wenn nichts freigegeben wird.Da Iteratoren quasi Zeiger sind, und die Objekte bei erase zerstört werden, zeigen die Iteratoren auf nichts gültiges mehr. Die Kapazität (=der vom Vektor belegte Speicher) bleibt aber erhalten.
-
EOutOfResources schrieb:
Nexus schrieb:
Zerstört ja, aber der Speicher bleibt belegt.
Standard 23.2.4.4 §3 schrieb:
iterator erase ( iterator position );
iterator erase ( iterator first , iterator last );
Effects: Invalidates iterators and references at or after the point of the erase
Verstehe ich den Standard falsch? Iteratoren sollten doch noch gültig sein, wenn nichts freigegeben wird.Das Löschen einer leeren Sequenz [it,it) macht trotzdem alle Iteratoren ab it ungültig und führt zu einer Menge Selbstzuweisungen. Das scheint mir ohnehin ein unwahrscheinlicher Fall zu sein, und der Standard schreibt nicht vor, dafür zu optimieren. Wenn man das ausnahmsweise mal braucht, kann man diesen Fall ja vor dem Aufruf von erase abfangen. Das ist dann ganz analog zum Test auf Selbstzuweisung.
-
Nach dem Aufruf von clear() Methode, hat der Vector size() = 0, also 0 Elemente....aber man kann trotzdem über Index auf die vorherigen Elemente zugreifen...was macht überhaupt die clear Methode denn...sie erfüllt ja ihre Aufgabe nicht...
-
goldenBoy schrieb:
...
Im Beispiel hast du
at()verwendet. Das sollte eigentlich werfen. Über den ungeschützten Zugriff, könntest du Glück haben und deine Daten wiederfinden. Wenn du den Speicher freigeben willst, solltest du den Swap-Trick nutzten.
-
goldenBoy schrieb:
Nach dem Aufruf von clear() Methode, hat der Vector size() = 0, also 0 Elemente....aber man kann trotzdem über Index auf die vorherigen Elemente zugreifen...was macht überhaupt die clear Methode denn...sie erfüllt ja ihre Aufgabe nicht...
Doch. clear hat nicht die Aufgabe, den Speicher wieder ans Betriebssystem zurückzugeben. clear macht nur den Speicher irgendwie leer, damit er wieder mit push_back gefüllt werden kann.
Willste den Specher freigeben, um den vector gar nicht mehr zu benutzen, wirf doch den ganzen vector weg.
-
std::vector::resize mit 0 sollte den kompletten Speicher freigeben.
-
Ethon schrieb:
std::vector::resize mit 0 sollte den kompletten Speicher freigeben.
Wenn mit "Speicher freigeben" gemeint ist, dass die Kapazität auf 0 gesetzt wird, dann nein.
Da hilft aktuell nur das "Clear-and-minimize"-Idiom:std::vector<T> vec; // some code... std::vector<T>().swap(vec); //clear and minimize
-
Tachyon schrieb:
Ethon schrieb:
std::vector::resize mit 0 sollte den kompletten Speicher freigeben.
Wenn mit "Speicher freigeben" gemeint ist, dass die Kapazität auf 0 gesetzt wird, dann nein.
Da hilft aktuell nur das "Clear-and-minimize"-Idiom:std::vector<T> vec; // some code... std::vector<T>().swap(vec); //clear and minimizeIst das ein Tippfehler oder vertauschst du wirklich
vecmit dem Konstruktor, ohne dich dabei auf ein bestimmtes Objekt zu beziehen? Wie funktioniert denn das?
-
vector<T>::clear und vector<T>::resize(0) machen das selbe: Sie rufen die Destruktoren für alle Elemente auf. Der Speicher, in dem die Elemente gelegen haben, gehört weiterhin dem vector. Wenn der Destruktor von T keine Zuweisungen an die Member des T-Objektes macht, wird an dem Speicher, den das T-Objekt belegt, nichts geändert. Trotzdem hört das Objekt als solches auf zu existieren. Das mit der Lebensdauer des Objektes ist ein pures Konzept, es hat nichts mit physikalischen Veränderungen am Speicher zu tun!
Da der Speicher also weiterhin dem vector gehört und die T-Destruktoren den belegten Speicher nicht geändert haben, sieht der Speicher genauso aus wie vorher. Zugriffe mit Pointern, operator[] und ehemaligen Iteratoren können also den Eindruck vermitteln, dass da immernoch das Objekt liegt. Ist aber alles undefiniertes verhalten. Eine Implementierung könnte z.B. im Debugmodus bei Destruktoren den vom Objekt belegten Speicher implizit ausnullen, dann wäre das Verhalten anders (und immernoch konform, da undefiniert).
Ich hoffe das stellts einigermaßen klar
-
[Rewind] schrieb:
Tachyon schrieb:
std::vector<T> vec; // some code... std::vector<T>().swap(vec); //clear and minimizeIst das ein Tippfehler oder vertauschst du wirklich
vecmit dem Konstruktor, ohne dich dabei auf ein bestimmtes Objekt zu beziehen? Wie funktioniert denn das?Nicht mit dem Konstruktor. Mit dem durch
std::vector<T>()erzeugten temporären Objekt.
-
Skym0sh0 schrieb:
.. ist dem seine sache
oha