C++: Как я могу решить исключение первого шанса, вызванное в неизвестной точке?
Проект C++, над которым я работаю, заканчивается после создания исключения первого шанса. Это происходит в Visual Studio 2008 в режиме отладки, когда я впервые пытаюсь получить доступ к map<pair<int,int>, int>
который содержит одну пару ключ-значение. Нет ничего логически неправильного в коде.
Я прочитал об исключениях первого шанса и понимаю, что они не всегда могут быть проблематичными. Тем не менее я попытался устранить все такие исключения, и, как и ожидалось, было сгенерировано несколько таких, которые не вызывают проблем.
Класс, над которым я работаю, очень большой и содержит много пользовательских распределений памяти. Я предполагаю, что каким-то образом одна из них вызывает проблему. Однако я потратил несколько часов, пытаясь найти способ определить, что происходит, и не смог этого сделать.
Результат исключения первого шанса приведен ниже. Это не очень полезно!
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.
Я действительно борюсь с этим и не знаю, как поступить.
Кто-нибудь может подсказать, как мне решить эту проблему, и точно определить, что происходит не так? Буду очень признателен за ваш совет.
ОБНОВИТЬ
Вот соответствующий код. Отладчик прерывается в первом операторе 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
Вот изображение описания наведения мыши для рассматриваемой карты; он кажется испорченным, как предположил Майкл Барр.
1 ответ
В общем, чтобы точно определить место кода, где происходит сбой приложения, вы можете включить обработку исключений в разделе "Отладка / Исключения". В этом случае вы бы развернули последнюю ветку и проверили Access Violation. Конечно, это остановит все нарушения доступа, а не только плохие (доступ 0x10). Вы можете минимизировать это, включив ловушку в последний известный момент.
Обычно вы обнаружите некоторую ошибку использования памяти. Самый простой способ определить причину ошибки такого типа - сторонний инструмент, такой как BoundChecker, который будет кричать на вас, как только вы повредите память. Не имея этого, совет Рэймонда Чена незаменим. Выясните, какой объект не так, и используйте окно просмотра, чтобы увидеть, когда он изменился. Или, более эффективно, используйте функцию "Точка останова данных", чтобы программа остановилась при изменении данных по определенному адресу.