Uebungen 9.12 - 9.14
-
David_pb schrieb:
thordk schrieb:
klar werden die elemente entfernt. vielleicht nicht physisch, aber logisch. size liefert die anzahl der elemente im vector, nicht capacity.
Ja das ist es ja aber.
Physisch sind die Elemente noch da und über operator[] kannst du sogar noch reinschreiben.weil [] keinerlei kontrolle unternimmt, ob du auf gültigen speicherbereich zugreifst oder nicht. greif mal mit vector#at(int) drauf zu.
-
David_pb schrieb:
Physisch sind die Elemente noch da und über operator[] kannst du sogar noch reinschreiben.
?
Ich würde mal sagen nach einem resize(size) auf ne kleinere Größe werden alle Elemente nach size gelöscht. Der Speicher für diese Elemente ist natürlich noch da.
-
thordk schrieb:
David_pb schrieb:
thordk schrieb:
klar werden die elemente entfernt. vielleicht nicht physisch, aber logisch. size liefert die anzahl der elemente im vector, nicht capacity.
Ja das ist es ja aber.
Physisch sind die Elemente noch da und über operator[] kannst du sogar noch reinschreiben.weil [] keinerlei kontrolle unternimmt, ob du auf gültigen speicherbereich zugreifst oder nicht. greif mal mit vector#at(int) drauf zu.
Genau so ist das. Aber da der Speicher noch vorhanden ist, ist es auch nicht "illegal" über auf Elemente über begin()+size() zu schreiben. Die Elemente sind ja noch vorhanden!
Wenn du die Größe des vectors genau anpassen willst kannst du das wie folgt machen:std::vector< int >( vec ).swap( vec );Dann hast du ganz genau so viel Elemente wie size() zurückgibt.
-
Ich würde sagen ein Zugriff auf einen Index ausserhalb 0 <= x < size() ist schlichtweg undefiniert. Da ist vollkommen egal was capacity() aussagt.
-
es ist auch nicht "illegal" sowas zu machen:
int *p; *p = 23;in 9 von 10 fällen geht sowas sogar gut, weil der pointer zufällig auf irgendnen bereich verweist, auf den keine ocke anspruch erhebt. aber beim 10. mal krachts.
wenn ich nen vector resize und dann auf bereiche zugreife, die "hinter" dem letzten element liege, dann hat das dieselben auswirken. es mag in 9 von 10 fällen gut gehen, aber im 10. fall hat sich deine vector implementierung dafür entschieden, genau in den bereich seine capacity zu schreiben und wo ursprünglich eine 12 stand, bretzelst du ihm ne 723.399 hin.. ups.
-
thordk schrieb:
wenn ich nen vector resize und dann auf bereiche zugreife, die "hinter" dem letzten element liege, dann hat das dieselben auswirken. es mag in 9 von 10 fällen gut gehen, aber im 10. fall hat sich deine vector implementierung dafür entschieden, genau in den bereich seine capacity zu schreiben und wo ursprünglich eine 12 stand, bretzelst du ihm ne 723.399 hin.. ups.
Sicher?
Standard schrieb:
-4- Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.
Ich seh hier nirgends etwas das der Speicher freigegeben werden muss. Darum sollte es zu 100% sicher sein über begin()+size() zu schreiben. Man schreibt ja nicht über den reservierten Speicherbereich hinaus.
-
David_pb schrieb:
Ich seh hier nirgends etwas das der Speicher freigegeben werden muss. Darum sollte es zu 100% sicher sein über begin()+size() zu schreiben. Man schreibt ja nicht über den reservierten Speicherbereich hinaus.
da steht auch nicht, dass er es nicht muss.
-
was der standard (bzw. die spezifikation) nicht ausdrücklich definiert, ist undefiniert. solange im standard weder steht, dass der speicher ausdrücklich freigegeben werden muss oder ausdrücklich reserviert bleiben muss, ist es einer implementierung frei überlassen, wie sie das umsetzt. die meisten werden bei so einer lockeren definition darauf verzichten, den speicher explizit freizugeben, aber eine andere macht es womöglich nicht.
-
Klar, aber eine Freigabe würde die Kompexität der Funktion verändern. Und die scheint ja vorgegeben zu sein. Naja, ein guter Gedanke sowas zu tun ist es trotzdem nicht.
-
David_pb schrieb:
Klar, aber eine Freigabe würde die Kompexität der Funktion verändern. Und die scheint ja vorgegeben zu sein. Naja, ein guter Gedanke sowas zu tun ist es trotzdem nicht.
es ist ein gedanke, den man gar nicht erst fassen sollte, weil er schlicht zu fehlerhaftem code führt.
-
Mag sein, aber kannst du das auch belegen?
-
und am ende ist noch zu beachten, dass der vector theoretisch den freien arrayplatz nutzen kann wie er lustig ist, zb zum speicherblockverschieben...
-
Wie wärs mit DevCPP ?
Der ist kostenlos...
-
Aaah, ich kann's mir nicht verkneifen …
Wieso braucht man mehr als eine Zeile, um eine Zahl in einem Vektor zu suchen?!
template <typename It> bool contains(It begin, It end, int num) { return begin != end and (*begin == num or contains(begin + 1, end, num)); }
-
weil ich so eine funktion lieber nicht mit 500k elementen aufrufe *G
-
thordk schrieb:
weil ich so eine funktion lieber nicht mit 500k elementen aufrufe *G
Merde, der VC++ schafft es tatsächlich nicht, die Endrekursion zu erkenne.
Schade.
-
Um mal die ganze Diskussion über die Speichernutzung des vector<>s abzukürzen: Die Kapazität des vector's verringert sich im Normalbetrieb nicht, die Größe schon. Und was im Bereich zwischen begin()+size() und begin()+capacity() steht, liegt ganz im Zuständigkeitsbereich des vector's (faktisch ist das Datenmüll, den der Anwender nicht nutzen sollte). Das bedeutet insbesondere, daß die überschüssigen Elemente beim Kopieren verloren gehen und bei der nächsten Größenänderung überschrieben werden können (der vector geht davon aus, daß sie nicht genutzt werden, also wird es sich auch nicht um sie kümmern). Bei einem vector<int> kann das tatsächlich gut gehen, aber z.B. bei einem vector<string> provozierst du mit sowas Access Violations.
PS: Und wenn schon einen Einzeiler, dann lieber so:
template<typename It,typename Val> bool contains(It begin,It end,const Val& v) { return std::find(begin,end,v) != end; }
-
CStoll schrieb:
PS: Und wenn schon einen Einzeiler, dann lieber so:
Das weiß bestimmt Konrad. Nur er hat in letzter Zeit immer so ein Einzeiler-Rekursiv-Tick

-
CStoll schrieb:
PS: Und wenn schon einen Einzeiler, dann lieber so:
Na, es ging ja darum, es selber zu implementieren und nicht Bibliotheksfunktionen zu verwenden.
-
Konrad Rudolph schrieb:
CStoll schrieb:
PS: Und wenn schon einen Einzeiler, dann lieber so:
Na, es ging ja darum, es selber zu implementieren und nicht Bibliotheksfunktionen zu verwenden.
Also wenn die STL verboten ist, sollte man das auch dazusagen (aber dann würde es auch wenig Sinn machen, mit vector zu hantieren).