Что может привести к тому, что указатель VTable будет равен 0xdddddddd в отладочной сборке Win32?

Я отлаживаю дефект и сузил его до указателя vtable для объекта 0xdddddddd. Этот ответ указывает, что отладочные сборки Win32 обычно устанавливают мертвую память или память, которая была удалена, на это специальное значение.

Обратите внимание, что сам указатель выглядит правильным, это всего лишь указатель vtable, который равен 0xdddddddd.

Вот фрагмент кода:

std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
    IMyObject* pMyObject = *it;
    if (pMyObject == 0)
        continue;

    pMyObject->someMethod(); // Access violation     
}

Если я прерву строку нарушения доступа и посмотрю pMyObject, я увижу, что сам pMyObject имеет действительный адрес (0x08ede388), но член __vfptr недействителен (0xdddddddd).

Некоторые примечания:

  • Это однопоточное приложение, поэтому, скорее всего, это не проблема гонки или мьютекса.
  • Кажется, нет никаких очевидных проблем, таких как удаление объекта дальше по стеку вызовов перед доступом к нему.
  • Эта проблема, по-видимому, воспроизводится только на сервере Windows 2008, но не в Windows 7.

Любые предложения о том, как отлаживать это дальше?


person LeopardSkinPillBoxHat    schedule 19.04.2011    source источник
comment
Это похоже на классический случай, когда кто-то удаляет объект после помещения указателя в список. Вы уверены, что это не так (он может быть удален из какой-то другой функции после заполнения списка, поэтому просмотр стека вызовов может не помочь). Самое простое, что можно попробовать, это поставить точку останова в деструкторе IMyObject и увидеть, что кто-то удаляет объект.   -  person Naveen    schedule 19.04.2011


Ответы (4)


Вы используете указатель после того, как он был освобожден. Получите трассировку стека из точки останова в деструкторе, чтобы увидеть, что его удаляет. Или, что еще лучше, используйте shared_ptr‹>, чтобы избежать этой проблемы.

person janm    schedule 19.04.2011
comment
Спасибо, эти объекты создаются/уничтожаются 1000 раз, так что это может быть сложно (даже не уверен, что условная точка останова поможет, потому что я не уверен, каким будет условие). Но я начну расследование. - person LeopardSkinPillBoxHat; 19.04.2011
comment
Вы ищете случай, когда объект удаляется без удаления указателя из списка, или случай, когда объект может быть вставлен в список более одного раза, но удален из списка только один раз при удалении. - person janm; 19.04.2011
comment
@LeopardSkinPillBoxHat: ... или случай, когда объект добавляется в список, а затем удаляется за пределами списка. Простой подход заключается в том, чтобы избегать необработанных указателей и хранить один из доступных интеллектуальных указателей (хорошим кандидатом может быть QSharedPointer). - person David Rodríguez - dribeas; 19.04.2011

Если вы запускаете программу, поставьте точку останова там, где вы создаете объект. Затем добавьте точку прерывания памяти. Это сработает, если вы перезапишете или удалите память. Ну или изменить его как-нибудь.

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

Это также может быть проблемой размера, если вы используете наследование. Если вы используете какую-либо память ведра или храните объекты чем-либо, кроме указателя.

person Tavison    schedule 19.04.2011

Если pMyObject->someMethod() в конечном итоге изменит список myObjects, он сделает недействительным любой из текущих итераторов.

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

person user3015455    schedule 21.11.2013
comment
Ах, недопустимые итераторы! Не думал об этом. - person Andrew; 29.05.2018

Итак, я много лет программировал на C++ и никогда не обнаруживал этого до сих пор... На самом деле существуют магические числа/магические значения отладки, которые вы можете найти, чтобы увидеть, что происходит с вашим необработанным кодом. указатели во время отладки!

См. здесь: Что такое память в Visual Studio C++? представления распределения?

и здесь: https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_debug_values

person Andrew    schedule 28.05.2018