C ++ редкая ошибка во время выполнения - PullRequest
0 голосов
/ 02 декабря 2011

У меня есть класс B, который наследует класс A с некоторыми виртуальными функциями.Класс B также имеет виртуальную функцию (foo), которая, кажется, не имеет адреса.Когда я иду с отладчиком, он указывает, что у foo есть адрес 0x00000000, и когда я пытаюсь войти в него, произойдет сбой с нарушением доступа на 0x00000005.Если я сделаю эту функцию не виртуальной, включится отладчик и будет работать нормально, пока я не достигну std::vector.Там, когда я вызываю push_back, произойдет сбой с тем же нарушением доступа по адресу 0x000000005 при записи некоторых вещей по адресу 0xabababab, и стек вызовов указывает на блокировку мьютекса в функции вставки.

ПримечаниеЯ не использую никакой другой поток, и инкрементный компоновщик будет зависать каждый раз, когда я компилирую.Только полный линкер успешно создаст исполняемый файл.Компилятор из Visual Studio 2008 pro, и эта проблема начала возникать при удалении неиспользуемых исходных файлов и исходного кода.

К сожалению, мне не удалось вернуться к предыдущему состоянию, чтобы определить изменение, которое его создало.

Как я могу определить источник проблемы, не возвращая весь проект?Также кто-нибудь сталкивался с такой ошибкой, возможно, это может быть той же причиной.

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

Вы предполагаете, что виртуальная таблица повреждена, но это маловероятно, поскольку виртуальные таблицы обычно хранятся в постоянной памяти.

Я могу вспомнить две причины такого поведения:

  • Используемый вами объект был удален. Он может работать случайно, если память, в которой находился объект, но с треском проваливается, если он перезаписывается.
  • Используемый вами объект не относится к динамическому типу B. Может быть, это тип A или, возможно, не связанный тип.

Я успешно отследил такого рода проблемы с отладкой printf : добавьте несколько строк с printf("XXX %p", this); в конструктор B, деструктор, виртуальные функции и функцию с ошибками, и вы быть в состоянии сделать вывод, что происходит.

Да, я знаю, отладка printf не круто ...

2 голосов
/ 02 декабря 2011

Вы вызываете виртуальную функцию по нулевому указателю.Компилятор добавляет код, который будет использовать скрытый указатель в объекте для определения того, что является окончательным переопределителем, и эта операция не выполняется.Когда вы изменяете функцию на не виртуальную, вызов отправляется статически, но опять же, доступ к элементам завершается неудачно, так как указатель this равен нулю.

Необходимо проверить действительность объекта, на котором вы находитесьвызов метода в вашем коде.

...