У меня есть код, который дает сбой в большой системе.Однако код по существу сводится к следующему псевдокоду.Я удалил большую часть деталей, поскольку я пытался свести это к голым костям;Я не думаю, что это пропускает что-то решающее, хотя.
// in a DLL:
#ifdef _DLL
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP __declspec(dllimport)
#endif
class DLLEXP MyClass // base class; virtual
{
public:
MyClass() {};
virtual ~MyClass() {};
some_method () = 0; // pure virtual
// no member data
};
class DLLEXP MyClassImp : public MyClass
{
public:
MyClassImp( some_parameters )
{
// some assignments...
}
virtual ~MyClassImp() {};
private:
// some member data...
};
и:
// in the EXE:
MyClassImp* myObj = new MyClassImp ( some_arguments ); // scalar new
// ... and literally next (as part of my cutting-down)...
delete myObj; // scalar delete
Обратите внимание, что используются соответствующие скалярное новое и скалярное удаление.
Вотладочная сборка в Visual Studio (2008 Pro), в Microsoftследующее утверждение не выполняется:
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
В верхней части стека находятся следующие элементы:
mydll_d.dll!operator delete()
mydll_d.dll!MyClassImp::`vector deleting destructor'()
Я думаю, это должно быть
mydll_d.dll!MyClassImp::`scalar deleting destructor'()
То есть программа ведет себя так, как если бы я написал
MyClassImp* myObj = new MyClassImp ( some_arguments );
delete[] newObj; // array delete
Адрес в pUserData
- это адрес самого myObj
(в отличие от члена).Память вокруг этого адреса выглядит следующим образом:
... FD FD FD FD
(address here)
VV VV VV VV MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
FD FD FD FD AB AB AB AB AB AB AB AB EE FE EE FE
...
, где четыре VV
s, предположительно, являются адресом таблицы виртуальных функций, MM...MM
- это распознаваемые данные члена, а другие байты различны.специальные маркеры, установленные отладчиком (например, FD FD
s являются «защитными байтами» вокруг хранилища объекта).
Незадолго до ошибки подтверждения я вижу изменение VV
s и задаюсь вопросом,это связано с переключением на таблицу виртуальных функций базового класса.
Мне известно о проблеме неправильного уровня в иерархии классов, подвергающейся разрушению.Это не проблема здесь;все мои деструкторы являются виртуальными.
Я отмечаю страницу Microsoft "BUG: неверное удаление оператора, вызванное для экспортируемого класса" http://support.microsoft.com/kb/122675, но это, похоже, связано с неверным исполняемым файлом (с неправильной кучей)взять на себя ответственность за уничтожение данных.
В моем случае это то, что применяется неправильный «аромат» удаления деструктора: т.е. вектор, а не скаляр.
Я нахожусь впроцесс создания минимального сокращенного кода, который все еще демонстрирует проблему.
Тем не менее, любые советы или подсказки, которые помогут в дальнейшем расследовании этой проблемы, будут высоко оценены.
Возможно,самая большая подсказка здесь - это mydll_d.dll!operator delete()
в стеке.Должен ли я ожидать, что это будет myexe_d.exe!operator delete()
, что означает, что DLLEXP
s были «потеряны»?
Я полагаю, это может быть случай двойного удаления (но я так не думаю).
Могу ли я прочитать хорошую справку о том, что проверяет _CrtIsValidHeapPointer
?