Я затрудняюсь объяснить, что, по-видимому, неправильно адресуется в массивах char[]
класса C ++, который я унаследовал. Я использую Visual Studio 2005 и сузил проблему до этого:
MyClass.h:
class MyClass {
public:
MyClass();
virtual ~MyClass();
void Reset();
// More member functions. . .
char m_szString[128];
// More member variables. . .
}
MyClass.cpp:
MyClass::MyClass() { Reset(); }
MyClass::Reset() { m_szString[0] = 'X'; }
// . . .
В процессе пошагового выполнения программы я обнаружил, что функция Reset()
фактически устанавливает m_szString[
4
]
на 'X'
& mdash; не m_szString[
0
]
, как я ожидал. Согласно окну наблюдения, единственным элементом в классе до m_szString[]
является указатель на vftable, __vfptr
, который составляет 4 байта.
Если я добавлю больше переменных-членов к MyClass
, последующие строки будут неправильно адресованы различными, постоянно увеличивающимися кратными 4 байтами. Не просто выровненные с 4-байтовыми границами, но на самом деле смещение на кратные 4. Это как если бы компилятор пропускал вдвое необходимое пространство для каждой vftable ... но это чисто думаю.
Сообщалось о некоторых похожих проблемах (Google, MSDN), но я не нашел ответов.
Дополнительная информация / Частичное решение: Этот класс является единственной переменной-членом класса-оболочки, который становится DLL. Родитель был первоначально объявлен как
class ATL_NO_VTABLE CWrapperClass
Удаление ATL_NO_VTABLE
исправило проблему с выравниванием.
Я все еще вижу переполнения буфера, но их довольно легко отследить.
Можете ли вы объяснить ATL_NO_VTABLE
в терминах, понятных для разработчика встроенного C, который имел очень ограниченный опыт работы с COM, помимо BSTR, или, что еще лучше, предоставить указатель (извините) на хорошую ссылку?
Еще больше: Этот вопрос предоставляет полезную информацию об отладке.
Спасибо за вашу помощь.