From 1724f902a116480e7ced4194d6c07531e27c1963 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 4 Jul 2017 12:47:13 +0200 Subject: [PATCH] Fix incorrect use of iterators. Iterators always create problems when using them on a list that is modified during iteration. --- pcbnew/editedge.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/pcbnew/editedge.cpp b/pcbnew/editedge.cpp index 81b3d9d8aa..0787d1229f 100644 --- a/pcbnew/editedge.cpp +++ b/pcbnew/editedge.cpp @@ -160,14 +160,15 @@ void PCB_EDIT_FRAME::Delete_Drawings_All_Layer( PCB_LAYER_ID aLayer ) if( !IsOK( this, msg ) ) return; - PICKED_ITEMS_LIST pickList; - ITEM_PICKER picker( NULL, UR_DELETED ); - BOARD_ITEM* PtNext; + // Step 1: build the list of items to remove. + // because we are using iterators, we cannot modify the drawing list during iterate + // so we are using a 2 steps calculation: + // First, collect items. + // Second, remove items. + std::vector list; for( auto item : GetBoard()->Drawings() ) { - PtNext = item->Next(); - switch( item->Type() ) { case PCB_LINE_T: @@ -175,11 +176,7 @@ void PCB_EDIT_FRAME::Delete_Drawings_All_Layer( PCB_LAYER_ID aLayer ) case PCB_DIMENSION_T: case PCB_TARGET_T: if( item->GetLayer() == aLayer ) - { - item->UnLink(); - picker.SetItem( item ); - pickList.PushItem( picker ); - } + list.push_back( item ); break; @@ -193,11 +190,22 @@ void PCB_EDIT_FRAME::Delete_Drawings_All_Layer( PCB_LAYER_ID aLayer ) } } - if( pickList.GetCount() ) + if( list.size() == 0 ) // No item found + return; + + // Step 2: remove items from main list, and move them to the undo list + PICKED_ITEMS_LIST pickList; + ITEM_PICKER picker( NULL, UR_DELETED ); + + for( auto item : list ) { - OnModify(); - SaveCopyInUndoList(pickList, UR_DELETED); + item->UnLink(); + picker.SetItem( item ); + pickList.PushItem( picker ); } + + OnModify(); + SaveCopyInUndoList(pickList, UR_DELETED); }