2012-04-23 65 views
0

什么我实现更复杂一点,所以我已经剥离下来的代码独立列表之间语句,并作出最简单的例子可能是复制问题:顺序插入/擦除导致赛格故障

我列出一个和B,在某些时候,我需要将1个元素从列表A移动到列表B.此对象在当前列表中存储其位置(迭代器)。它适用于1个列表,插入和删除。尽管如此,当在列表A的迭代周期内更改列表B时,我发现执行插入和擦除指令的顺序决定了我是否遇到seg错误。下面是代码:

typedef struct AO_ { 
    int id; 
    list<AO_*>::iterator thispos; 
} AnObject; 

class MyList { 
    public: 

    list<AnObject*> ll; 
    int sizell; 

    MyList(){ sizell=0; } 

    void insert(AnObject* AnObjecti){ 
     AnObjecti->thispos= ll.insert(ll.end(),AnObjecti); 
     sizell++; 
    } 

    list<AnObject*>::iterator remove(AnObject* AnObjecti){ 
     return ll.erase(AnObjecti->thispos); 
    } 

    void print(){ 
     cout << "contents:"; 
     list<AnObject*>::iterator itAux; 
     for (itAux=ll.begin(); itAux!=ll.end(); itAux++) 
     cout << " " << (*itAux)->id; 
     cout << endl;    
    }   
}; 

int main(int argc, char *argv[]){ 

    MyList* listA= new MyList(); 
    MyList* listB= new MyList(); 
    AnObject* objAux= new AnObject(); 

    for(int i=0; i<10; i++){ 
     objAux= new AnObject(); 
     objAux->id= i; 
     listA->insert(objAux); 
    } 

    cout << "list A:" << endl; listA->print(); 

    list<AnObject*>::iterator it= listA->ll.begin(); 
    while(it!=listA->ll.end()){ 
     objAux= (*it); 
     if(objAux->id==2){ 
      //listB->insert(objAux); //***THIS CAN GO HERE (seg fault on next cycle) 
      it= listA->remove(objAux);  
      listB->insert(objAux); //***OR THIS CAN GO HERE (all ok) 
     } 
     else 
      ++it; 
    } 

    cout << "list A:"; listA->print(); 
    cout << "list B:"; listB->print(); 
} 

和输出:

list A: 
contents: 0 1 2 3 4 5 6 7 8 9 
list A:contents: 0 1 3 4 5 6 7 8 9 
list B:contents: 2 

我得到一个赛格故障,如果交换的指示标记由* 是否有人知道为什么吗?

在此先感谢 何塞

回答

1

listB->insert的调用修改objAux->thispos指新的列表。然后,对listA->remove的调用将尝试在其调用list::erase时使用该迭代器。将错误容器的迭代器传递给erase会导致未定义的行为。