2012-03-21 15 views
5

Ho un problema mentre lavoro con i vettori di una classe. Ho provato a ridurre il più possibile il codice, lasciandomi il seguente codice. Eppure, dopo averlo fatto, non riesco ancora a capire perché il mio programma stia andando in crash. Vengo da un mondo di VBA e le mie capacità di debug del C++ sono a dir poco scarse e mi scuso per questo in anticipo. Qualsiasi guida per migliorare la mia abilità qui sarà accettata volentieri.vector.push_back() si blocca

La mia classe:

class Tester { 
public: 

    int varA; 
    int varB; 

    Tester() { 
     varA = 1; 
     varB = 1; 
    } 

    Tester(Tester& P1, Tester& P2) { 
     varA = P1.varA + P2.varA; 
     varB = P1.varB + P2.varB; 
    } 

    Tester(const Tester &Source) { 
     varA = Source.varA; 
     varB = Source.varB; 
    } 

}; 

miei rete di prova:
non funziona:

int main() { 
std::vector <Tester> BreakIt; 

    for (int i = 0; i < 2500; i++) { 
     Tester newTester; 
     BreakIt.push_back(newTester); 
     Tester& tempTester = BreakIt.at(0); 
     for (int j = 0; j < 4; j++) { 
      BreakIt.push_back(Tester(newTester, tempTester)); //This is where it crashes. 
     } 
    } 

return 0; 
} 

Fa lavoro:

int main() { 
std::vector <Tester> BreakIt; 

    Tester newTester; 
    BreakIt.push_back(newTester); 

    for (int i = 0; i < 2500; i++) { 
     Tester& tempTester = BreakIt.at(0); 
     for (int j = 0; j < 4; j++) { 
      BreakIt.push_back(Tester(newTester, tempTester)); 
     } 
    } 

return 0; 
} 

funziona:

int main() { 
std::vector <Tester> BreakIt; 

    for (int i = 0; i < 2500; i++) { 
     Tester newTester; 
     BreakIt.push_back(newTester); 
     Tester& tempTester = BreakIt.at(0); 
    } 

return 0; 
} 

La linea push_back() che rompe viene eseguito un paio di volte prima del crollo. Sembra che quando cambio certe cose intorno e ricompilate, il punto in cui si blocca cambia (cioè 20 volte attraverso il ciclo principale contro 175 volte contro 1000 volte). Tuttavia, una volta compilato, in genere viene eseguito la stessa iterazione ogni volta prima di bloccarsi.

Sospetto che si tratti di un "comportamento indefinito" ma da cui non sono sicuro.

Qualcuno può aiutarmi a identificare perché BreakIt.push_back(Tester(newTester, tempTester)); non funziona dove lo voglio?

+1

proposito, non utilizzare'Per (int i = 1; i <5; i ++) ', è un inutile confusione, utilizzare'Per (int i = 0; i <4; i ++)' invece. Inoltre, stai ridefinendo'i' nel ciclo interno, che è anche molto confuso ed estremamente incline ai bug. – enobayram

+0

@enobayram Hai assolutamente ragione sulla ridefinizione! – Gaffi

risposta

15

Hai ragione, c'è un comportamento indefinito.

Si sta prendendo un riferimento a BreakIt.at(0); tuttavia non è più garantito che questo oggetto esista dopo aver eseguito uno push_back, perché se il vettore aumenta, tutti i contenuti vengono in genere copiati e gli originali eliminati.

Da http://www.cplusplus.com/reference/stl/vector/push_back/ (non migliore di riferimento del mondo):

Riassegnazioni invalidare iteratori tutti precedentemente ottenuti, riferimenti e puntatori.

+0

Beh, originariamente era 'for (int iTesterLoop = 0; iTesterLoop <(int) BreakIt.size(); iTesterLoop ++) {' seguito da 'Tester & tempTester = BreakIt.at (iTesterLoop);' ma questo non funzionava ancora, quindi stavo cercando di ridurre ulteriormente il codice. Quanto sopra in questo commento non ha funzionato. – Gaffi

+0

Ok. È possibile/accettabile quindi creare un altro vettore, aggiungere i miei nuovi elementi nel ciclo, quindi aggiungere gli elementi dal vettore temporaneo all'esterno del ciclo? C'è un'alternativa migliore? – Gaffi

+0

@Gaffi: Puoi farlo, ma perché non solo 'BreakIt.push_back (Tester (newTester, BreakIt.at (0)))'? –