2012-09-20 10 views
7
//fills my vector with pointers. 
//(some are pointing places, others are set to nullptr 
vector<Tree_NodeT*> xml_trees {Build_Tree_List(program_options->Get_Files())}; 

//time to print them 
for (auto tree = xml_trees.begin(); tree != xml_trees.end(); ++tree){ 
    if (*tree){ 
     (*tree)->Print(std::cout,4); 
    } 
} 
//this worked! No Segfaults! 

//time to print them again 
for (auto tree : xml_trees){ 
    if (tree){ 
     tree->Print(std::cout,4); 
    } 
} 
//Crash! Segfault. 

Perché il secondo ciclo segfaulting, mentre il primo ciclo non lo è?Basato su intervallo per loop in C++ 11 segfault, ma non con ciclo regolare per

+0

Puntatore dereferenziazione? Non ne ho idea, sto solo pensando al mio culo –

+3

Per chiarire, non ho ancora esperienza con C++ 11, ma perché non ti trasferisci nel secondo ciclo? - Sto assumendo le auto dereferenze C++ per te? –

+1

@ AK4749, 'tree' nel secondo ciclo è ogni' Tree_NodeT * 'nel vettore, dove nel primo ciclo, è più come un puntatore al' Tree_NodeT * '. – chris

risposta

2

MODIFICA:
Sono un bugiardo.
I puntatori Tree_NodeT sono stati creati, ma non inizializzati su nullptr da qualche parte nella funzione Build_Tree_List. Quindi, ho ottenuto un vettore in cui alcuni dei puntatori stavano puntando a memoria valida, e altri erano solo puntatori appena costruiti non impostati su null o dati alcun indirizzo. È comunque interessante notare che il primo ciclo è stato in grado di gestirlo senza crash, mentre il secondo è stato segmentato.

+6

Questa è la natura del comportamento indefinito, non è definita in modo che tutto possa accadere, anche [i demoni che volano fuori dal tuo naso] (http://www.catb.org/jargon/html/N/nasal-demons.html). –

+0

Preferisco il comportamento indefinito di un attacco missilistico nucleare sulla superficie di Marte. –

2

L'intervallo per il ciclo equivale a:

for (auto it = xml_trees.begin(); it != xml_trees.end(); ++it) { 
    auto tree = *it; 
    if (tree){ 
     (tree)->Print(std::cout,4); 
    } 
} 

La differenza è che la gamma di loop è l'iteratore Dereferenced costruzione di copia. Per ottenere un comportamento simile al ciclo for tradizionale, utilizzare :

for (auto &tree: xml_trees){ 
    if (tree){ 
     tree->Print(std::cout,4); 
    } 
} 
+0

Non capisco, l'iteratore dereferenziato è solo un 'Tree_NodeT *', quindi copiare-costruire (copiare) non dovrebbe causare alcun problema. – Praetorian

+0

@ Prætorian hmm, si. Suppongo che potrebbe anche essere la ripetuta chiamata di "end()" invece di chiamarla all'inizio. – ecatmur