Zeigerstandorte garantiert?

8

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>     

tweetypi 05.01.2012, 04:49
quelle

7 Antworten

7
  

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.

    
Mysticial 05.01.2012, 04:52
quelle
4

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.

    
chrisaycock 05.01.2012 04:53
quelle
4

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.

    
Dietmar Kühl 05.01.2012 04:57
quelle
4

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%     
bobobobo 07.10.2012 18:04
quelle
2

Nein - der Vektor kann neu zugewiesen werden, wenn er wächst. Normalerweise verdoppelt sich der Vektor einmal.

Aus dem C ++ 11-Standard

%Vor%     
Adrian Cornish 05.01.2012 04:52
quelle
2

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.

    
pinerd314159 05.01.2012 04:57
quelle
2

Sobald Sie die Kapazität des Vektors geändert haben, wurden die Daten in einen anderen Speicherblock kopiert, und die Ursprungsdaten werden gelöscht.

    
benlong 05.01.2012 05:23
quelle

Tags und Links