0

私が実装しているのはもう少し複雑なので、コードを取り除き、問題を再現する最も単純な例を作成しました:

リスト A と B があり、ある時点でリスト A からリスト B に 1 つの要素を移動する必要があります。このオブジェクトは、現在オンになっているリストの位置 (反復子) を記憶します。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

*でマークされた指示を交換すると、セグフォルトが発生 します。誰かが理由を知っていますか?

前もって感謝します

4

1 に答える 1

1

への呼び出しは、新しいリストを参照するようにlistB->insert変更します。objAux->thispos次に、 への呼び出しは、 への呼び出しlistA->removeでその反復子を使用しようとしますlist::erase。間違ったコンテナーから反復子を渡すと、erase未定義の動作が発生します。

于 2012-04-23T17:35:09.047 に答える