2011-12-18 10 views
6

Projekt C++, nad którym pracuję, kończy się po wyrzuceniu wyjątku pierwszej szansy. Dzieje się tak w programie Visual Studio 2008 w trybie debugowania, gdy po raz pierwszy próbuję uzyskać dostęp do map<pair<int,int>, int>, która zawiera jedną parę klucz-wartość. Nie ma nic logicznie nie w porządku z kodem.C++: Jak mogę rozwiązać wyjątek pierwszej szansy spowodowany w nieznanym momencie?

Przeczytałem o wyjątkach pierwszej szansy i rozumiem, że nie zawsze są problematyczne. Mimo to próbowałem przełamać wszystkie takie wyjątki i zgodnie z oczekiwaniami znaleziono kilka, które nie powodują problemów.

Klasa, nad którą pracuję jest bardzo duża i zawiera wiele niestandardowych alokacji pamięci. Przypuszczam, że jakoś jeden z nich powoduje problem. Spędziłem jednak kilka godzin, próbując znaleźć sposób, aby zidentyfikować, co dzieje się nie tak i nie mogłem tego zrobić.

Wyjścia wyjątku pierwszej szansy są wymienione poniżej. To nie jest bardzo pomocne!

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. 

Naprawdę walczę w tej kwestii i nie jestem pewien, jak postępować.

Czy ktoś może zasugerować, w jaki sposób mogę rozwiązać ten problem i określić, co dokładnie dzieje się nie tak? Byłbym bardzo wdzięczny za twoją radę.

UPDATE

Tutaj jest związany kod. Przerwy debugger na pierwszym rachunku cout wymienionych w zagnieżdżonych 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... 

UPDATE 2

Oto obraz opisu przesunięć myszy na mapie w pytaniu; wygląda na zepsuty, jak sugerował Michael Burr.

enter image description here

+2

Nie jest to wyjątek pierwszej szansy, który powoduje jego zakończenie, jest to nieobsługiwany wyjątek. –

+1

Nie znam MSVS, ale w jakiś sposób "naruszenie zasad dostępu" powoduje, że wątpię, że "kod nie jest niczym złym" ... –

+0

Mówisz: "Nie ma nic logicznie nie w porządku z kodem.". Wszystko wskazuje na to, że coś jest nie tak z kodem. Czy możesz pokazać nam linię kodu (z odpowiednimi wcześniejszymi liniami). –

Odpowiedz

9

Generalnie, aby wskazać miejsce kodu, w którym awarii aplikacji, można włączyć obsługę wyjątków pod Debug/wyjątki. W takim przypadku należy rozwinąć ostatnią gałąź i sprawdzić naruszenie dostępu. Oczywiście to zatrzyma się na wszystkich naruszeniach dostępu, a nie tylko złym (dostęp do 0x10). Możesz zminimalizować to, włączając pułapkę w ostatnim znanym momencie.

Zazwyczaj można zauważyć błąd użycia pamięci. Najprostszym sposobem ustalenia przyczyny tego typu błędu jest narzędzie innej firmy, takie jak BoundChecker, które będzie krzyczeć na ciebie, gdy tylko uszkodzisz pamięć. Bez tego Raymond Chen ma rację. Sprawdź, który obiekt jest zły, i skorzystaj z okna zegarka, aby zobaczyć, kiedy to się zmieniło. Lub bardziej wydajnie, użyj funkcji Data Breakpoint, aby zatrzymać program, gdy zmieni się dane pod konkretnym adresem.

+0

Dziękuję za te informacje, Alan. Moje przeprosiny za tak długi czas, aby zaznaczyć swoją odpowiedź! – KomodoDave

Powiązane problemy