2013-11-20 3 views
6

Iniziamo con questo codice di esempio in C++:comportamento strano di riferimento vector.back() dopo vettore viene modificata

#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<int> vec; 
    vec.push_back(0); 
    for (int i = 1; i < 5; i++) 
    { 
     const auto &x = vec.back(); 
     std::cout << "Before: " << x << ", "; 
     vec.push_back(i); 
     std::cout << "After: " << x << std::endl; 
    } 
    return 0; 
} 

Il codice viene compilato con g++ test.cc -std=c++11 -O0 e seguenti è il risultato:

Before: 0, After: 0 
Before: 1, After: 0 
Before: 2, After: 2 
Before: 3, After: 3 

mi aspettavo la seconda linea di uscita per essere

Before: 1, After: 1 

dal x è un riferimento a un elemento nel vettore, che non deve essere modificato aggiungendo elementi al vettore.

Tuttavia non ho letto il codice smontato o non ho fatto altre indagini per ora. Inoltre, non so se si tratta di un comportamento indefinito nello standard del linguaggio.

Voglio che questo sia spiegato. Grazie.

risposta

8

push_back possono causare riallocazione, se guardiamo le draft C++ standard sezione 23.3.6.5modificatori vettore dice:

vuoto push_back (const T & x);

void push_back (T & & x);

Osservazioni: Provoca riallocazione se la nuova dimensione è superiore alla vecchia capienza. Se no avviene la riallocazione, tutti gli iteratori e i riferimenti prima che il punto di inserimento rimanga valido.

possiamo vedere che back ci dà un di riferimento e quindi se c'è una riallocazione esso non sarà più valida .

4

vector gli iteratori (ei riferimenti precedenti agli elementi) possono essere invalidati dopo la modifica del vettore. Usarli non è sicuro.

+1

Ci dispiace, ma non c'è nulla di correlato con gli iteratori. – starrify

+0

@starrify: prova a procurarti una copia invece di un riferimento al valore dietro "indietro". –

+0

@KirilKirov Sì, questo è anche quello che sospetto, e voglio essere sicuro che questo sia il problema (citando lo standard o leggendo il codice assembly generato o whatelse) – starrify