Can anybody show me what's going on here? To begin with, I believe most developers realize that a category having a virtual function includes a vtbl and therefore has 4 extra bytes on top of it. So far as I understand, that's fairly standard. I have examined this and cheated this fact before to complete load in position from the binary file with patched vtbls. During the last 6 several weeks, I have been employed in Xcode and merely lately discovered the necessity to perform some load in position stuff, and so i was considering patching vtbls again. Simply to make certain my understanding was correct, I authored an example program. Here you go:

class A
{
    public:
    virtual int getData()
    {
        return a;
    }

    virtual void print()
    {
        printf("hello\n");
    }
    int a;
};

class B : public A
{
public:
    int getData()
    {
        return b;
    }
    int b;
};

class C : public B
{
public:
    int getData()
    {
        return c;
    }

    void print()
    {
        printf("world\n");
    }
    int c;
 };

class D
{
public:
    int a;
    int b;
};

int main (int argc, const char * argv[])
{
    A* tA = new A();
    tA->a = 1;

    printf("A: %d\n", sizeof(A));
    printf("A data: %d\n", tA->getData());

    B* tB = new B();
    tB->a = 2;
    tB->b = 4;

    printf("B: %d\n", sizeof(B));
    printf("B data: %d\n", tB->getData());

    C* tC = new C();
    tC->c = 8;

    printf("C: %d\n", sizeof(C));
    printf("C data: %d\n", tC->getData());

    A* aC = tC;
    aC->print();

    printf("D: %d\n", sizeof(D));

    return 0;
}

My expected output was:

A: 8

An information: 1

B: 12

B data: 4

C: 16

C data: 8

world

D: 8

However, the output I am getting is:

A: 16

An information: 1

B: 16

B data: 4

C: 24

C data: 8

world

D: 8

Anybody have idea what's happening here? Thanks!

Cases of classes A through C have a vptr, a pointer towards the virtual function table for that dynamic type. This pointer occupies 8 bytes in your 64-bit machine (or 4 bytes on the 32-bit machine). Each int member occupies 4 bytes.

The minimum worth of sizeof(Class) is the sum of the sizeof(member) for those people. Whether it were really like that, then

sizeof(A) = 8 (vptr) + 4 (int a) = 12
sizeof(B) = 8 (vptr) + 4 (int a) + 4 (int b) = 16
sizeof(C) = 8 (vptr) + 4 (int a) + 4 (int b) + 4 (int c) = 20
sizeof(D) = 4 (int a) + 4 (int b) = 8

However, this is simply the minimum size. Compilers usually increase this size to some multiple of sizeof(void*), that is 8 bytes here. This method is known as aiming. It might seem like this wastes memory, but this really is outweighed with a performance gain: The CPU can see aligned data considerably faster than non-aligned data.

Incidentally, your expected result could have been correct should you be on the 32-bit machine. Pointers (esp. vptr) are 4 bytes wide there, and alignment can also be to multiples of four bytes. Since all data people from the classes under consideration are 4 bytes large then, alignment wouldn't do anything whatsoever there.