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

Tại sao vòng lặp thứ hai segfaulting, trong khi vòng lặp đầu tiên không?Dựa trên phạm vi cho các vòng lặp trong C++ 11 segfault, nhưng không thường xuyên đối với vòng lặp

+0

Dereference con trỏ? Không có ý tưởng, chỉ cần suy nghĩ ra khỏi ass của tôi –

+3

Để làm rõ, không có kinh nghiệm với C++ 11 được nêu ra, nhưng tại sao bạn không dereference trong vòng thứ hai? - Tôi giả định C++ tự động dereferences cho bạn? –

+1

@ AK4749, 'cây' trong vòng lặp thứ hai là mỗi' Tree_NodeT * 'trong vectơ, trong đó trong vòng lặp đầu tiên, nó giống như một con trỏ tới' Tree_NodeT * '. – chris

Trả lời

2

EDIT:
Tôi là kẻ nói dối.
Các con trỏ Tree_NodeT đã được tạo, nhưng không được khởi tạo thành nullptr ở đâu đó trong hàm Build_Tree_List. Vì vậy, tôi đã có một vector trở lại nơi một số con trỏ trỏ đến bộ nhớ hợp lệ, và những người khác chỉ mới được xây dựng con trỏ không được thiết lập để null hoặc đưa ra bất kỳ địa chỉ. Điều thú vị là vòng đầu tiên đã có thể xử lý điều này mà không bị rơi, trong khi vòng lặp thứ hai bị phân đoạn.

+6

Đó là bản chất của hành vi không xác định, nó không xác định để bất cứ điều gì có thể xảy ra, ngay cả [quỷ bay ra khỏi mũi bạn] (http://www.catb.org/jargon/html/N/nasal-demons.html). –

+0

Tôi thích hành vi không xác định của một cuộc tấn công tên lửa hạt nhân trên bề mặt sao Hỏa. –

2

phạm vi của bạn cho vòng lặp là tương đương với:

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

Sự khác biệt là phạm vi cho vòng lặp là bản sao-xây dựng iterator dereferenced. Để có được hành vi tương tự với vòng lặp truyền thống của bạn, hãy sử dụng auto &:

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

Tôi không hiểu, trình lặp lặp lại chỉ là 'Tree_NodeT *', vì vậy sao chép-xây dựng (sao chép) nó sẽ không gây ra bất kỳ sự cố nào. – Praetorian

+0

@ Prætorian hmm, vâng. Đoán nó cũng có thể là sự kêu gọi lặp đi lặp lại của 'end()' trái ngược với việc chỉ gọi nó ngay từ đầu. – ecatmur

Các vấn đề liên quan