sizeof(*this) gives wrong value

By : Rob
Source: Stackoverflow.com
Question!

I have a class, C. C has a member variable declared as: bool markerStart;

From within C a call to sizeof(*this) gives a value of 0x216 bytes.

Elsewhere within C, I do: markerStart = false;

Rather than setting markerStart to false, this call is actually clobbering the start of the next class in memory!

Looking at the disassembled code, I find:

markerStart = false;
06FB6B7F mov            eax, dword ptr [this]
06FB6B78 mov            byte ptr [eax+218h], 0

The second move instruction is setting a byte at this + 0x218 to zero, but since the class is only 0x216 bytes long, this is clobbering memory!

In response to a comment, it definitely is the markerStart = false instruction. I can watch it happening in the disassembler view and in the memory view (and using Windbg, by using a data breakpoint). The first byte of the next class gets set to zero, which messes up its vftbl pointer.

Note: taking the address of markerStart and subtracting it from this, yields 0x211!

Can anyone give me a clue on where to start looking to resolve this problem?

Update: Thanks for all the help. Without code, it was next to impossible for any of you to solve the problem. What I was looking for were hints as to where to start looking. Most of you provided excellent hints, so thank you!

I finally found the problem. In this case alignment had been set in one class, and not been correctly reset following the critical block of code. The class with the faulty alignment happened to get compiled immediately before the declaration of class C - hence that's where the problem showed up.

By : Rob


Answers

The problem you are encountering is probably due to some dependency errors rather than anything wrong with the compiler (compilers are used by hundreds of thousands of developers and if there's a problem like this it would have been found by now).

Consider a simple project with the following two files. File a.cpp:

class C
{
public:
  C () : m_value (42) { }
  void Print () { cout << "C::m_value = " << m_value << endl; }
private:
  int m_value;
};

void DoSomethingWithC (C &c);

void main (void)
{
  C array_of_c [2];
  DoSomethingWithC (array_of_c [0]);
  array_of_c [0].Print ();
  array_of_c [1].Print ();
}

and file b.cpp:

class C
{
public:
  int a,b;
};

void DoSomethingWithC (C &c)
{
  c.b = 666;
}

If you compile the above two files and link them you won't get any errors or warnings. However, when you run the application, you'll find that DoSomethingWithC clobbers array_of_c [1] even though its argument is array_of_c [0].

So your problem could be that one source file sees the class one way and another file sees it a different way. This can happen if the dependancy checking fails.

Try forcing a rebuild all. If that works then you'll need to see why the dependcies have failed (DevStudio, for example, can get it wrong sometimes).

By : Skizz


Check that *this really points to the start of the class rather than a call via a bad pointer.

By : Joshua


Have your class definitions or project settings changed at all recently? I've seen problems like this, where I was getting absolutely absurd behaviors like this, and the cause was stale object files being linked. The object files no longer matched the source files. Try a clean and complete rebuild.

By : Rob K


This video can help you solving your question :)
By: admin