当我尝试在cygwin中运行程序时,我执行的以下功能导致错误“异常终止(核心已转储)”。我尝试使用gdb,我得到:
“程序收到信号SIGABRT,已中止。
0x00000000 in ?? ()”
我先尝试先擦除您,然后再擦除,但这会产生相同的结果,即在第二次擦除期间崩溃(在这种情况下为delete(me))。
CoalesceOverlaps函数的基本思想是组合自身重叠的OVERLAP,因此我对列表进行排序,检查两个相邻的(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++;
}
}
}
最佳答案
我相信您的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;
...等等。删除“我”后,
thee
不再有效。以读取方式访问它是未定义的行为,但是可能会起作用,因为在引用的数据指针上仍然存在某些内容。但是,最终通过erase()
调用来表现出来的仍然是未定义的行为。