http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53225
--- Comment #27 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-05-04 22:09:10 UTC --- (In reply to comment #8) > >No, that's not how it works. If Base::increment() writes to Base::field then > >it > >is always at the same offset into the Base object. Whether that Base object > >is > >a sub-object of another clas is irrelevant. > > I apologize, as I don't know how else to put it but in multiple inheritance > that statement is just plain wrong. Fields move. You can see it in the debug > output at the link, the field for 'count' moved by 4 bytes from what it was in > the parent to where it is located in the child. Try this: #include <iostream> typedef unsigned int uint; class C{ // just here to be faithful to the original code int y; }; class A{ public: uint count; }; class B : public C, public A{ public: int i; }; int main(){ B b; B* bp = &b; A* ap = &b; std::cout << "B* " << bp << '\n'; std::cout << "A* " << ap << '\n'; std::cout << "B::count " << &bp->count << '\n'; std::cout << "A::count " << &ap->count << '\n'; } The address of the same object gives two separate values. See? B* 0x7fffb5ba8f90 A* 0x7fffb5ba8f94 B::count 0x7fffb5ba8f94 A::count 0x7fffb5ba8f94 But the count member accessed through both is the same, because there's a different offset to access A::count inside an A (offset 0) and to access A::count inside a B (offset 4) So if you access bp->count and ap->count you are accessing the same member, at the same location, but through a different offset. So inside your operator new where you are trying to allocate a B, when you access the count member through (A*) you get the wrong location, because you have memory for a B (which contains an A, at offset 4) but are treating it as though it was just an A.