2011-12-18 39 views
6

我正在处理的C++项目在抛出一次性异常时终止。当我第一次尝试访问包含单个键值对的map<pair<int,int>, int>时,这发生在Visual Studio 2008的调试模式下。代码没有任何逻辑错误。C++:如何解决在未知点引起的一次机会异常?

我已经阅读了一次机会例外,并了解它们可能并不总是有问题。尽管如此,我试图打破所有这些例外,并且如预期的那样发现了几个不会造成问题的东西。

我正在处理的类非常大,并且包含许多自定义内存分配。我猜想,其中有一个导致了这个问题。然而,我花了几个小时试图找到一种方法来确定哪里出了问题,并且一直无法这样做。

下面列出了第一次机会异常输出。这不是很有帮助!

First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x762cd09c in theapp.exe: 0xC0000005: Access violation reading location 0x6c696d00. 
First-chance exception at 0x0050ae33 in theapp.exe: 0xC0000005: Access violation reading location 0x00000010. 
Unhandled exception at 0x0050ae33 in theapp.exe: 0xC0000005: Access violation reading location 0x00000010. 

在这一点上我真的很挣扎,而且我不确定如何继续。

任何人都可以建议我如何解决这个问题,并确切地确定出了什么问题?我非常感谢你的建议。

UPDATE

下面是相关的代码。在列出的第一个COUT语句中的调试器中断嵌套FOR:

 // Inside operator() : 

     map<pair<int,int>,int> resultIdByStructIds; 
     pair<int,int> spair (-1,-1); // Structure pair ids reusable reference. 

     int nextMapEntryId = 0; 
     int nextNumCandidates = 0; 
     // For each remaining candidate. 
     for (int ci = 0; ci < numCandidates;) { 
      // If candidate has been mapped or found not viable this mapping round, 
      // move past it. 
      if (candidatesDoneThisRound[ci] == currentMappingRoundId) { 
       ++ci; 
       continue; 
      } 

      Candidate candidate = candidates[ci]; 
      const int tId = candidate.tVertexId; 
      const int pId = candidate.pVertexId; 

      // Grab the result for this structure pair. 
      // Create it if it doesn't exist. 
      // Avoid copying as slight optimisation; simply 
      // store pointer to true result instead. 
      spair.first = tInfos[tId].structure->id; 
      spair.second = pInfos[pId].structure->id; 

      // DEBUG 
      cout << "resultIdByStructIds size: " << resultIdByStructIds.size() << endl; 
      for (map<pair<int,int>,int>::const_iterator ids_id = resultIdByStructIds.begin(); ids_id != resultIdByStructIds.end(); ++ids_id) { 
       cout << ids_id->first.first << endl; // * Debugger breaks here. 
       cout << ids_id->first.second << endl; 
       cout << ids_id->second << endl; 
       printf("Structures(%i,%i) => %i\n",ids_id->first.first,ids_id->first.second,ids_id->second); 
      } 
      // 

      // code continues... 

更新2

下面是有问题的地图鼠标悬停描述的图像;它看起来像迈克尔伯尔建议的那样损坏了。

enter image description here

+2

这不是第一次偶然的异常使它终止,它是未处理的异常。 – 2011-12-18 23:08:55

+1

我不知道MSVS,但以某种方式“访问冲突”让我怀疑“代码没有问题”...... – 2011-12-18 23:11:11

+0

你说:“代码没有任何逻辑错误。”目前为止的所有迹象都表明代码有问题。你能告诉我们一行代码(与相关的前面的行)。 – 2011-12-18 23:13:54

回答

9

一般情况下,要找准代码的那个地方的应用程序崩溃,您可以打开例外下调试/例外处理。在这种情况下,您将展开最后一个分支并检查访问冲突。当然,这将停止所有的访问冲突,而不仅仅是坏的(访问0x10)。您可以通过在最后一个已知时刻打开陷阱来尽量减少这种情况。

通常你会发现一些内存使用错误。确定这种类型的错误的最简单方法是像BoundChecker这样的第三方工具,只要你损坏了内存,它就会大声吼你。由于缺乏这一点,Raymond Chen的建议就显现出来了。找出哪个对象是错误的,并使用观察窗口来查看它何时改变。或者更高效地使用数据断点功能,在特定地址的数据发生变化时使程序停止。

+0

谢谢你提供这些信息,Alan。我很抱歉花了这么长时间来打勾你的答案! – KomodoDave 2013-04-25 13:25:14

相关问题