2012-09-20 15 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. 

¿Por qué es el segundo bucle segfaulting, mientras que el primer bucle no lo es?Basado en rango para bucles en C++ 11 segfault, pero no con regular para bucle

+0

Desreferencia del puntero? No tengo idea, solo pienso en mi trasero –

+3

Para aclarar, aún no tienes experiencia con C++ 11, pero ¿por qué no deferencias en el segundo ciclo? - Estoy asumiendo auto deferencias de referencia de C++ para usted? –

+1

@ AK4749, 'tree' en el segundo bucle es cada' Tree_NodeT * 'en el vector, donde en el primer bucle, se parece más a un puntero al' Tree_NodeT * '. – chris

Respuesta

2

EDITAR:
Soy un mentiroso.
Se crearon punteros Tree_NodeT, pero no se inicializó en nullptr en algún lugar de la función Build_Tree_List. Por lo tanto, obtuve un vector en el que algunos de los apuntadores apuntaban a la memoria válida, y otros solo eran punteros recién construidos, no configurados como nulos o con ninguna dirección. Todavía es interesante que el primer bucle fue capaz de manejar esto sin estrellarse, mientras que el segundo segfaulted.

+6

Esa es la naturaleza del comportamiento indefinido, no está definido para que pueda pasar cualquier cosa, incluso [los demonios salen volando de tu nariz] (http://www.catb.org/jargon/html/N/nasal-demons.html). –

+0

Prefiero el comportamiento indefinido de un ataque con misiles nucleares en la superficie de Marte. –

2

Su rango de bucle es equivalente a:

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

La diferencia es que el rango de bucle es copia-construir el iterador sin referencia. Para obtener un comportamiento similar al del bucle for tradicional, use auto &:

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

No lo entiendo, el iterador sin referencias es solo 'Tree_NodeT *', por lo tanto, copiar-construir (copiar) no debería causar ningún problema. – Praetorian

+0

@ Prætorian hmm, sí. Supongo que también podría ser la llamada repetida de 'end()' en lugar de simplemente llamarlo al principio. – ecatmur

Cuestiones relacionadas