1

私が作成した次の関数は、cygwinでプログラムを実行しようとすると、「Aborted(coredumped)」というエラーを引き起こします。gdbを使用してみたところ、次のようになりました。

「プログラム受信信号SIGABRT、中止。0x00000000in ??()」

私は最初にあなたを消去し、次に私を消去しようとしましたが、これは同じ結果を生成し、2回目の消去(この場合はerase(me))中にクラッシュします。

CoalesceOverlaps関数の基本的な考え方は、オーバーラップするOVERLAPを組み合わせるというものです。リストを並べ替え、隣接する2つの(meとthee)要素がオーバーラップしていないか確認し、オーバーラップする場合は、meとtheeの組み合わせである新しい要素を作成します。 、私とあなたを削除し、それらを組み合わせである新しい要素に置き換えます。

この関数は、要素でいっぱいの手のハードコードされたリストでテストし、出力が正しく合体したため、論理的に機能しますが、大きなリスト/空のリストなどがある実際のプログラムに実装しようとすると失敗します。

編集(cnvr_check_v1.1.exe.stackdumpから):

Stack trace:
Frame     Function  Args
0028A624  76E31194  (000000E8, 0000EA60, 00000000, 0028A758)
0028A638  76E31148  (000000E8, 0000EA60, 000000A4, 0028A734)
0028A758  610DC559  (00000001, 80038390, 0000001D, 610EBCCC)
0028A848  610D9913  (00000000, 0028A890, 0028A878, 61187784)
0028A8A8  610D9DEE  (0028FF14, 00000001, 0028A8E8, 00000006)
0028A958  610D9F40  (00000158, 00000006, 0053002B, 61187784)
0028A978  610D9F6C  (00000006, 00000006, 0028A9A8, 610B66D1)
0028A9A8  610DA233  (00000000, 0028A9DC, 0028A9C8, 610FD3CA)
End of stack trace

コード:

void CoalesceOverlaps(list<OVERLAP>& overlap_regions)
{
cout << "Begining of CoalesceOverlaps function\n";
overlap_regions.sort(OVERLAPStartSortPredicate);
//now coalesce
cout << "Didn't fail during sorting\n";

list<OVERLAP>::iterator me = overlap_regions.begin(),
                           end = overlap_regions.end();

if ( me != end ) // Treat empty list
    for(list<OVERLAP>::iterator thee = ++me; // Post-increment 
        thee != end; 
        me++, thee++)
    {

        cout << "just before thee-> start less than... if\n";
        //cout << me->stop << endl;
        if(thee->start <= me->stop) //hit to coalesce them
        {
            cout << "thee->ID:" << thee->id << endl;
            cout << "thee->start:" << thee->start << endl;
            cout << "made it to the thee->start less than me->stop if\n";
            long temp_start = min(thee->start,me->start),temp_stop = max(thee->stop,me->stop);
            OVERLAP temp_region;
            temp_region.start = temp_start;
            temp_region.stop = temp_stop;
            cout << "just before the first erase\n";
            //overlap_regions.push_front(temp_region);
            list<OVERLAP>::iterator temp_itr = overlap_regions.erase(me);

            cout << "thee->ID:" << thee->id << endl;
            cout << "thee->start:" << thee->start << endl;

            cout << "just before the second erase\n";
            //cout << thee->id;
            overlap_regions.erase(thee);
            cout << "past the erases\n";
            overlap_regions.insert(temp_itr,temp_region);
        }
        cout << "bottom of the for\n";
    }
cout << "End of CoalesceOverlaps function\n";

}

編集(以下の修正された機能)ありがとう!:

void CoalesceOverlaps(list<OVERLAP>& overlap_regions)
{
overlap_regions.sort(OVERLAPStartSortPredicate);

//iterators for keeping track of the two nodes we are comparing
list<OVERLAP>::iterator me = overlap_regions.begin(),
                        thee = overlap_regions.begin(),
                           end = overlap_regions.end();


if ( me != end ) // Treat empty list
    thee++; //sets it to the second element
    if(thee!=end)   //Treat list with one element
        while(thee != end)  //lets keep comparing until we right the end
        {
            if(thee->start <= me->stop) //hit to coalesce them
            {
                long temp_start = min(thee->start,me->start),temp_stop = max(thee->stop,me->stop);
                OVERLAP temp_region;
                temp_region.start = temp_start;
                temp_region.stop = temp_stop;

                overlap_regions.erase(me);

                list<OVERLAP>::iterator temp_itr = overlap_regions.erase(thee);

                me = overlap_regions.insert(temp_itr,temp_region);
                thee = temp_itr;
            }
            else{
                me++;
                thee++;
            }
        }
}
4

1 に答える 1

2

あなたのme消去はあなたのtheeイテレータを無効にしていると思います。

for(list<OVERLAP>::iterator thee = ++me; // Post-increment

これにより、それらがfor-initializerの同じノードであることが保証されます。コメントはポストインクリメントと言っています。それポストインクリメントではありません。したがって、これを行います。

list<OVERLAP>::iterator temp_itr = overlap_regions.erase(me);

すぐにこれが続きます:

cout << "thee->ID:" << thee->id << endl;
cout << "thee->start:" << thee->start << endl;

...等。'me'の消去後、theeは無効になります。読み取りのためにアクセスすることは未定義の動作ですが、参照されるデータポインターにまだ何かがあるため、おそらく機能します。erase()しかし、それでもなお、呼び出しで最終的に現れるのは未定義の動作です。

于 2013-01-02T16:01:57.330 に答える