【问题标题】:order of insert/erase statements between independent lists causing seg fault导致段错误的独立列表之间的插入/擦除语句的顺序
【发布时间】:2012-04-23 17:27:22
【问题描述】:

我正在实现的有点复杂,所以我已经剥离了代码,并制作了最简单的示例来复制问题:

我有列表 A 和 B,在某些时候我需要将 1 个元素从列表 A 移动到列表 B。这个对象记住它在当前列表中的位置(迭代器)。它适用于 1 个列表、插入和擦除。然而,当在列表 A 的迭代周期内更改列表 B 时,我发现执行插入和擦除指令的顺序决定了我是否遇到段错误。代码如下:

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

如果交换 * 标记的指令,我会遇到 seg 错误 有人知道为什么吗?

提前致谢 何塞

【问题讨论】:

    标签: c++ list insert erase


    【解决方案1】:

    listB-&gt;insert 的调用会修改objAux-&gt;thispos 以引用新列表。然后对listA-&gt;remove 的调用将尝试在对list::erase 的调用中使用该迭代器。将迭代器从错误的容器传递给 erase 会产生未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多