Основанный на диапазоне для циклов в C ++ 11 segfault, но не с обычным циклом for

//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.

Почему второй цикл является segfaulting, а первый — нет?

7

Решение

РЕДАКТИРОВАТЬ:
Я лжец.
Указатели Tree_NodeT создавались, но не инициализируется в nullptr где-то в функции Build_Tree_List. Таким образом, я получил вектор, в котором некоторые указатели указывали на действительную память, а другие были только что созданными указателями, для которых не было установлено нулевое значение или был задан какой-либо адрес. Интересно, что первый цикл мог справиться с этим без сбоев, а второй — с ошибками.

2

Другие решения

Ваш диапазон для цикла эквивалентен:

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

Разница в том, что диапазон для цикла — это создание копии разыменованного итератора. Чтобы получить поведение, подобное вашему традиционному циклу for, используйте auto &:

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