I'm at a loss to explain what seems to be mis-addressing within the char[]
arrays of a C++ class I've inherited. I'm using Visual Studio 2005 and have narrowed the problem down to this:
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'; }
// . . .
As I single-step through the program, I find that the Reset()
function actually sets m_szString[
4
]
to 'X'
— not m_szString[
0
]
as I expected. According to the watch window, the only element in the class before m_szString[]
is a pointer to the vftable, __vfptr
, which happens to be 4 bytes.
If I add more member variables to MyClass
, subsequent strings are mis-addressed by various, always-increasing multiples of 4 bytes. Not simply aligned to 4-byte boundaries, but actually offset by multiples of 4. It's as if the compiler is skipping twice the necessary space for each vftable ... but that's purely a guess.
Somewhat similar problems have been reported (Google, MSDN), but I haven't found any answers.
Additional Information / Partial Solution: The class is the only member variable of a wrapper class that becomes a DLL. The parent was originally declared as
class ATL_NO_VTABLE CWrapperClass
Removing ATL_NO_VTABLE
fixed the alignment problem.
I'm still seeing buffer overflows, but those should be fairly easy to track down.
Can you explain ATL_NO_VTABLE
in terms understandable to an embedded C developer who's had very limited experience with COM beyond BSTRs, or better yet, provide a pointer (sorry) to a good reference?
Still More: This question provides some helpful debugging information.
Thanks for your help.