2013-01-02 46 views
1

当我尝试在cygwin中运行我的程序时,我所做的以下功能导致错误“Aborted(核心转储)”。我尝试使用gdb的,我得到:“节目的接收信号SIGABRT,中止 00000000的?()”中止(核心转储)C++ Cygwin

我已经试过先擦除你我,但这个产生相同的结果,在第二次擦除期间崩溃(在这种情况下擦除(我))。

CoalesceOverlaps函数的基本思想是将自身重叠的OVERLAP组合在一起,所以我对列表进行排序,检查两个相邻的元素(如果它们重叠),并且如果它们重叠,则创建一个组合的新元素我的&你,删除我&你并用新的组合元素替换它们。

该函数的逻辑工作原理是当我用一个手工完成的元素的硬编码列表测试它时,输出结果是正确合并的,但是当我尝试在具有大列表/空列表等的真实程序中实现它时,它失败。

EDIT(来自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"; 

} 

EDIT(下面校正功能)谢谢!:

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++; 
      } 
     } 
} 
+0

你还可以提供转储吗? –

+0

您是否尝试在调试器下运行它以查看错误所在(gdb等)? – slugonamission

+0

@izomorphius - 我编辑原始帖子以包含转储。 – Robert

回答

2

我相信你的me擦除会使你的thee迭代器失效。

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

这保证它们是你的初始化器中的同一个节点。你的评论说,后增量。即不是后增量。因此,你再这样做:

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

本紧跟:

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

...等。擦除'我'后,thee不再有效。访问它来读取是未定义的行为,但可能会工作,因为仍有在引用的数据指针。但它是无限的未定义的行为,最终通过erase()调用表现出来。

+0

但我删除后,cout << "thee-> ID:“​​id << endl; cout << "thee-> start:”​​start << endl;仍然有效 – Robert

+1

看起来就是这样,因为节点还没有被覆盖。另一个问题是for语句中的“me ++,the ++”。擦除后无法做到这一点。 –

+0

@罗伯特见答案的最后一段。一旦你从迭代器中删除了元素,我相信你处于未定义行为(这意味着你不能依赖它工作,甚至不能工作)。我相信它最终会在清除电话中表现出来(可怕)。 – WhozCraig