0

Considering the following code:

class B
{
    public:

    int a=10;
    B()
    {
        cout << "B() at: "<<this<<endl;
        cout << "Sizeof: " << sizeof(*this) << endl;
        cout <<endl<<endl;
    }

    };

class D1: virtual public B
{
    public:

    int a=20;
    D1()
    {
        cout << "D1() at: "<<this<<endl;
        cout << "Sizeof: " << sizeof(*this) << endl;

        cout << *((int *) this) << endl;
        cout << *((int *) this+1) << endl;
        cout << *((int *) this+2) << endl;
        cout << *((int *) this+3) << endl; 
        cout <<endl<<endl;
    }
};

class D2: public D1
{
    public:

    int a=30;
    D2()
    {
        cout << "D2() at: "<<this<<endl;
        cout << "Sizeof: " << sizeof(*this) << endl;
        cout <<endl<<endl;
    }
};

When I instantiate a D2 object, the following output is given:

B() at: 0x22ff0c
Sizeof: 4


D1() at: 0x22ff00
Sizeof: 12
4659268
20
2293652
10


D2() at: 0x22ff00
Sizeof: 16

Is the size of D1 12 bytes because it contains its own integer, the integer inherited from B and a pointer to the vtable?

Why is there a gap between D1's space and B's space? (Why isn't 10 showing up exactly after 20?)

I thought that the memory layout of a D2 object would be something similar to this

***D2*************
*                * 
* ***D1***********
* *             ** 
* * vptr        **
* * int         **
* ****************
* int            * 
* **B*************
* *             ** 
* * int         **
* ****************
* ****************  

Is there any mistake in my imagined layout?

The compiler used is gcc.

user42768
  • 1,951
  • 11
  • 22
  • Since you exploit *undefined behavior* by using that pointer arithmetic in the `D1` constructor, the results you get is theoretically unusable. In practice though, if you know the [ABI](https://en.wikipedia.org/wiki/Application_binary_interface) and how the compiler lays out your object in memory it's *probably* okay. – Some programmer dude Jul 17 '15 at 12:01
  • The already posted question which was suggested does not explain why there are an extra 4 bytes inside the D1 object and what is stored there. – user42768 Jul 17 '15 at 12:07
  • I moved the code from D1's constructor's to D2's constructor. That gap was in fact used to store the integer that belongs to D2, but was uninitialized. So I believe the layout I thought of is correct. I apologize for the mistake. – user42768 Jul 17 '15 at 12:17

0 Answers0