Nulltes Element eines leeren std::vectors
-
Eine kurze Frage zur STL. Führt
std::vector<T> v; T* ptr = &v[0];zu undefiniertem Verhalten?
Der C++-Standard sagt zwar Folgendes:
§23.2.4/1 Class template vector schrieb:
A vector is a kind of sequence that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if
vis avector<T, Allocator>whereTis some type other thanbool, then it obeys the identity&v[n] == &v[0] + nfor all0 <= n < v.size().Wie ich das sehe:
- Aus der Gleichheit
&v[0] == &v[0] + 0schliesse ich nicht, dassv[0]bei leeren Containern überhaupt definiert ist. - Zumal im Fall von
v.size() == 0das Intervall0 <= n < 0angegeben ist (also eine leere Menge), scheint es mir eher so, als hätte man diesen Fall im Standard nicht miteinbezogen. - Generell ist ja die Semantik von
v[n]über*(v.begin() + n)definiert. Bei leeren Containern giltv.begin() == v.end(), wodurch man den Past-The-End-Iterator dereferenziert, also undefiniertes Verhalten hat.
Meiner Ansicht nach weist alles auf UB hin, sieht das jemand anders? Ist halt etwas schade, weil es die Generizität (gerade in Verbindung mit C-APIs) ziemlich einschränkt und Fallunterscheidungen nötig macht. Zumindest sofern man das streng nimmt.
- Aus der Gleichheit
-
also einen leeren
vectorvorausgesetzt...&v[0]kann IMO nicht definiert sein, dav[0]eine Referenz zurückgeben muss (ausgenommenvector<bool>natürlich).
und ich fände es äusserst fragwürdig, wenn dervectorzu diesem zweck einfach ein "dummy-element" anlegen bzw. eine (im derzeitigen standard "verbotene" bzw. nicht klar erlaubte) "null-referenz" zurückgeben dürfte.
da ich also keinen "erlaubten" rückgabewert fürv[0]wüsste, behaupte ich einfach mal dass es UB sein muss. und noch ein "&" davorzustellen ändert daran nichts.
-
Gibt es einen plausiblen Grund v[n] mit n==0 anders zu behandeln als jedes andere n, das die (un)Gleichun 0 <= n < v.size() nicht erfüllt? Ich denke nicht.
-
Wozu man so ein Quatsch auch brauchen soll???
-
Nexus schrieb:
Ist halt etwas schade, weil es die Generizität (gerade in Verbindung mit C-APIs) ziemlich einschränkt und Fallunterscheidungen nötig macht. Zumindest sofern man das streng nimmt.
Bei C musste auch prüfen, ob du nicht ein Array mit 0 Elementen hast. Das Verhalten von malloc(0) ist "implementation defined" entweder Nullzeiger oder ein ungültiger anderer Zeiger.
-
Ich finde einen Zeiger auf ein Array das es nicht gibt schon toll.
-
v[0] ist bereits nicht definiert, da 0<vec.size() gelten muss. das wird nur nicht abgefangen, siehe at().
-
Danke allen für die Bestätigung.
@ naaaaa und SeppJ:
Ich dachte halt an sowas:c_write_array(&v[0], v.size());Bei
v.size() == 0würde dann einfach nichts getan. Halt wie die STL-Algorithmen, welche ebenfalls mit leeren Sequenzen umgehen können.