VSC ++, виртуальный метод по неправильному адресу, любопытная ошибка - PullRequest
1 голос
/ 14 июня 2010

Этот парень:

virtual phTreeClass* GetTreeClass() const { return (phTreeClass*)m_entity_class; }

При вызове вылетала программа с нарушением прав доступа даже после полной перекомпиляции. Все функции-члены и виртуальные функции-члены имели правильные адреса памяти (я наводил указатель мыши на методы в режиме отладки), но эта функция имела неправильный адрес памяти: 0xfffffffc.

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

Итак, я удалил виртуальный, скомпилированный, и он работает нормально. Я добавляю виртуальный, скомпилированный, и он все еще работает отлично! Я практически ничего не изменил и помню, что раньше я делал полную перекомпиляцию, и тогда у меня все еще была ошибка.

Я не смог воспроизвести проблему. Но теперь он вернулся. Я ничего не изменил. Удаление виртуальных исправляет проблему.

Ответы [ 3 ]

2 голосов
/ 14 июня 2010

Никогда не используйте броски в стиле C с полиморфными типами, если вы не уверены в том, что делаете. Подавляющая вероятность, что вы приведете его к типу, которого не было. Если ваши указатели не приводятся неявно (потому что они приводятся к базовому классу, что безопасно), то вы делаете это неправильно.

0 голосов
/ 14 июня 2010

Учитывая, что перекомпиляция изначально устранила проблему, попробуйте сначала выполнить полную очистку и пересобрать.

Если это не удастся, то весьма вероятно, что, хотя ваш указатель this кажется вам правильным, он фактически удален / деконструирован и указывает на мусорную память, которая просто выглядит как реальный объект, который был там раньше , Если вы используете gdb для отладки, первое слово в указателе объекта будет vtable. Если вы сделаете x/16xw <addr> (например) дамп памяти в этом месте, GDB скажет вам, какой тип vtable объекта находится там. Если это родительский тип, то объект определенно пропал.

Альтернативно, если указатель this одинаков каждый раз, когда вы можете поместить точку останова в деструктор класса с условием, что this == known_addr.

0 голосов
/ 14 июня 2010

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

Иногда мы сталкиваемся с такими необъяснимыми проблемами и исправлениями. Существует миф о том, что удаление ncb-файла когда-то исправляло сборку.

...