darxsys
darxsys

Reputation: 1570

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.

Upvotes: 5

Views: 390

Answers (4)

shofee
shofee

Reputation: 2129

It's because your system may be 64-bit system, due to which it becomes,

  • 8 bytes for vptr.
  • 4 bytes for int
  • and additional 4 bytes padding to give 64-bit alignment to the pointer.

hence sum becomes 16.

Upvotes: 1

4pie0
4pie0

Reputation: 29724

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.

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254461

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.

Upvotes: 4

Luchian Grigore
Luchian Grigore

Reputation: 258598

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.

Upvotes: 5

Related Questions