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, который будет кричать на вас, как только вы повредите память. Не имея этого, совет Рэймонда Чена незаменим. Выясните, какой объект не так, и используйте окно просмотра, чтобы увидеть, когда он изменился. Или, более эффективно, используйте функцию "Точка останова данных", чтобы программа остановилась при изменении данных по определенному адресу.

Другие вопросы по тегам