1

当我尝试在 cygwin 中运行我的程序时,我创建的以下函数导致错误“Aborted(core dumped)”。我尝试使用 gdb 并得到:

“程序收到信号 SIGABRT,中止。0x00000000 in ?? ()”

我曾尝试先擦除你,然后再擦除我,但这会产生相同的结果,即在第二次擦除期间崩溃(在这种情况下擦除(我))。

CoalesceOverlaps 函数的基本思想是组合自身重叠的 OVERLAP,因此我对列表进行排序,检查两个相邻的(我和你)元素是否重叠,如果它们重叠,则创建一个新元素,即我和你的组合,删除 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;

...ETC。'我'删除后,thee不再有效。访问它以进行读取是未定义的行为,但可能会起作用,因为在引用的数据指针上仍有一些东西。但最终通过erase()调用表现出来的仍然是未定义的行为。

于 2013-01-02T16:01:57.330 回答