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

爲什麼是第二個循環segfaulting,而第一個循環不是?基於範圍for循環在C++ 11 segfault,但不是與正常for循環

+0

指針取消引用?不知道,只是想出我的屁股 –

+3

澄清,沒有C++ 11的經驗,但爲什麼你不在第二個循環中解除引用? - 我假設你使用C++自動解引用? –

+1

@ AK4749,第二個循環中的'tree'在向量中都是'Tree_NodeT *',在第一個循環中,它更像是一個指向'Tree_NodeT *'的指針。 – chris

回答

2

編輯:
我是個騙子。
Tree_NodeT指針正在創建,但而不是已初始化爲Build_Tree_List函數某處的nullptr。因此,我得到了一個向量,其中一些指針指向有效內存,而其他指針只是新構造的指針,沒有設置爲空或給定任何地址。仍然有趣的是,第一個循環能夠處理這個沒有崩潰,而第二個循環。

+6

這是未定義行爲的本質,​​它是未定義的,所以任何事情都可能發生,即使[惡魔從你鼻子裏飛出](http://www.catb.org/jargon/html/N/nasal-demons.html)。 –

+0

我更喜歡火星表面的核導彈攻擊的未定義行爲。 –

2

你的範圍內循環是等價於:

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

不同的是,for循環的範圍是拷貝構造iterator的反引用。要獲得與傳統for循環類似的行爲,請使用auto &

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

我不明白,取消引用的迭代器只是一個'Tree_NodeT *',所以拷貝構建(複製)它不應該引起任何麻煩。 – Praetorian

+0

@Prætorian嗯,是的。猜測它也可能是'end()'的重複調用,而不是在開始時調用它。 – ecatmur