Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Polymorphic memory cost

I have this chunk of code:

    #include <stdio.h>

    class CoolClass {
    public:
      virtual void set(int x){x_ = x;};
      virtual int get(){return x_;};
    private:
      int x_;
    };

    class PlainOldClass {
    public:
      void set(int x) {x_ = x;};
      int get(){return x_;}
    private:
      int x_;
    };
    int main(void) {
      printf("CoolClass size: %ld\n", sizeof(CoolClass));
      printf("PlainOldClass size: %ld\n", sizeof(PlainOldClass));
      return 0;
    }

I'm getting a little bit confused because it says that the size of CoolClass is 16? How? Why? Even with the pointer to the vtable, shouldn't the size be 8? Size of oldclass is 4 as expected.

edit: I'm running Linux Mint 64 bit with g++ 4.6.3.

like image 978
darxsys Avatar asked Apr 01 '13 11:04

darxsys


3 Answers

You can't assume anything about the sizes of anything other than char or unsigned char. If you're building on a 64 bit platform, int is likely still 4 bytes, but the size of the virtual table pointer would likely be 8, and the extra 4 bytes are for padding (so that the pointer is aligned to 8 bytes).

64-bit

+----+----+----+----+
| vp | vp | x_ | p  |
+----+----+----+----+

vp - virtual table pointer
x_ - member
p  - padding byte

32-bit

+----+----+
| vp | x_ |
+----+----+

vp - virtual table pointer
x_ - member
p  - padding byte

Padding not required because the pointer is already aligned

As a test, you can try

class PlainOldClass {
private:
  int* x_;
};

and its size would be 8.

like image 173
Luchian Grigore Avatar answered Nov 15 '22 14:11

Luchian Grigore


My best guess is that you're compiling for a platform with 64-bit pointers. Then you'll need 8 bytes for the virtual pointer, probably 4 bytes for the int (some 64-bit platforms will also give that 8 bytes - but you say that sizeof (PlainOldClass) is 4, so that doesn't apply here), and another 4 to give the class the 64-bit alignment required by the pointer - giving a total of 16 bytes.

like image 4
Mike Seymour Avatar answered Nov 15 '22 15:11

Mike Seymour


I think the cost is:

  • platform with 64-bit pointers, so 8 bytes for the virtual pointer
  • 4 bytes for the int (but might be also 8 bytes on some platforms)
  • 4 to give the class the 64-bit alignment required by the pointer

sum=16 bytes.

like image 2
4pie0 Avatar answered Nov 15 '22 15:11

4pie0