Я не могу объяснить, что, кажется, неправильно адресуется в 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'
, а не 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, или, что еще лучше, предоставить указатель (извините) на хорошую ссылку?
Еще больше: Этот вопрос содержит некоторую полезную информацию по отладке.
Спасибо за вашу помощь.