C ++: Как я могу решить исключение первого шанса, вызванное в неизвестной точке? - PullRequest
6 голосов
/ 19 декабря 2011

Проект 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.

Я действительно борюсь с этим и не знаю, как поступить.

Может кто-нибудь подсказать, как мне решить эту проблему, и точно определить, что происходит не так? Буду очень признателен за ваш совет.

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

1 Ответ

9 голосов
/ 16 февраля 2012

В общем, чтобы точно определить место кода, где происходит сбой приложения, вы можете включить обработку исключений в разделе «Отладка / Исключения».В этом случае вы бы развернули последнюю ветку и отметили нарушение прав доступа.Конечно, это остановит все нарушения доступа, а не только плохие (доступ 0x10).Вы можете минимизировать это, включив ловушку в последний известный момент.

Обычно вы обнаружите некоторую ошибку использования памяти.Самый простой способ определить причину ошибки такого типа - это сторонний инструмент, такой как BoundChecker, который будет кричать на вас, как только вы повредите память.Не имея этого, совет Рэймонда Чена очень важен.Выясните, какой объект не так, и используйте окно просмотра, чтобы увидеть, когда он изменился.Или более эффективно использовать функцию «Точка останова данных», чтобы программа остановилась при изменении данных по определенному адресу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...