Angenommen, ich habe einen Vektor von Ints,
%Vor%das mit einer Menge von Werten gefüllt ist, dann sage ich dies (wo ein Eintrag bei 43 existiert)
%Vor%Ist oneNumber garantiert immer auf das int bei Index 43 zu zeigen, auch wenn ich sage, dass ich Zahlen auf etwas wie numbers.resize (46) skaliere?
Ich bin nicht 100% sicher, welches erwartete Verhalten hier ist, ich weiß, dass Vektoren garantiert zusammenhängend sind, aber nicht sicher, ob diese Kontinuität auch bedeuten würde, dass alle Indizes im Vektor während ihres gesamten Lebens am selben Ort bleiben würden / p>
Ist oneNumber garantiert, immer auf das int bei Index 43 zu zeigen
Ja, das wird vom Standard garantiert.
, auch wenn ich sage, dass ich Zahlen auf etwas wie numbers.resize (46) skaliere?
Nein. Sobald Sie die Größe des Vektors ändern, hinzufügen oder entfernen, werden alle Adressen und Iteratoren ungültig. Dies liegt daran, dass der Vektor möglicherweise mit neuen Speicherorten neu zugewiesen werden muss.
Ihre Paranoia ist richtig. Durch Ändern der Größe von std::vector
kann sich der Speicherort ändern. Das bedeutet, dass oneNumber
jetzt auf einen alten Speicherbereich verweist, der freigegeben wurde. Daher ist der Zugriff darauf nicht definiert.
Zeiger, Referenzen und Iteratoren auf std::vector
-Elemente bleiben garantiert erhalten, solange Sie nur an die std::vector
and anhängen und die Größe von std::vector
nicht darüber hinaus wächst seine capacity()
zu dem Zeitpunkt, als der Zeiger, die Referenz oder der Iterator erhalten wurde. Sobald die Größe über capacity()
hinaus geändert wird, werden alle Zeiger, Referenzen und Iteratoren für diese std::vector
ungültig. Beachten Sie, dass Dinge auch ungültig gemacht werden, wenn Sie etwas anderes als das Ende von std::vector
einfügen.
Wenn Sie möchten, dass Ihre Objekte bleiben und Sie nur neue Elemente am Ende oder am Anfang einfügen, können Sie std::deque
verwenden. Zeiger und Verweise auf Elemente in std::deque
werden nur ungültig, wenn Sie in die Mitte von std::deque
einfügen oder wenn Sie aus der Mitte entfernen oder das referenzierte Objekt entfernen. Beachten Sie, dass Iteratoren für Elemente in std::deque
jedes Mal ungültig gemacht werden, wenn Sie ein Element in std::deque
einfügen oder ein Element daraus entfernen.
Wie alle anderen gesagt haben, wenn Sie .resize()
für einen Vektor aufrufen, werden Ihre Zeiger ungültig, weil das (alte) vollständig freigegeben werden kann und ein völlig neues zugewiesen werden kann und Ihre Daten hineinkopiert werden .
Eine Abhilfe hierfür ist keine Zeiger in einem AWL-Vektor speichern. Stattdessen speichert ganzzahlige Indizes .
Also in Ihrem Beispiel
%Vor%Nein - der Vektor kann neu zugewiesen werden, wenn er wächst. Normalerweise verdoppelt sich der Vektor einmal.
Aus dem C ++ 11-Standard
%Vor%Wenn Sie die resize () - oder reserve () -Funktion eines Vektors verwenden, um die Kapazität des Vektors zu erhöhen, muss der Speicher möglicherweise für das Array-Backing neu zugewiesen werden. Wenn es neu zugeordnet wird, befindet sich der neue Speicher nicht an der gleichen Adresse, so dass die in oneNumber gespeicherte Adresse nicht mehr auf die richtige Stelle zeigt.
Dies hängt wiederum davon ab, für wie viele Elemente der Vektor momentan gespeichert wird und wie groß die angeforderte Größe ist. Abhängig von den Besonderheiten kann der Vektor in der Lage sein, die Größe ohne Neuzuweisung zu ändern, aber Sie sollten definitiv nicht davon ausgehen, dass dies der Fall sein wird.