This is an online C++ test question, which has been done.
#include<iostream>
using namespace std;
class A
{
};
class B
{
int i;
};
class C
{
void foo();
};
class D
{
virtual void foo();
};
class E
{
int i ;
virtual void foo();
};
class F
{
int i;
void foo();
};
class G
{
void foo();
int i;
void foo1();
};
class H
{
int i ;
virtual void foo();
virtual void foo1();
};
int main()
{
cout <<"sizeof(class A) : " << sizeof(A) << endl ;
cout <<"sizeof(class B) adding the member int i : " << sizeof(B) << endl ;
cout <<"sizeof(class C) adding the member void foo() : " << sizeof(C) << endl ;
cout <<"sizeof(class D) after making foo virtual : " << sizeof(D) << endl ;
cout <<"sizeof(class E) after adding foo virtual , int : " << sizeof(E) << endl ;
cout <<"sizeof(class F) after adding foo , int : " << sizeof(F) << endl ;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(G) << endl ;
G g;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(g) << endl ;
cout <<"sizeof(class H) after adding int 2 virtual " << sizeof(H) << endl ;
return 0;
}
output:
sizeof(class A) : 1
sizeof(class B) adding the member int i : 4
sizeof(class C) adding the member void foo() : 1
sizeof(class D) after making foo virtual : 8
sizeof(class E) after adding foo virtual , int : 16
sizeof(class F) after adding foo , int : 4
sizeof(class G) after adding foo , unsigned int : 4
sizeof(class g) after adding foo , unsigned int : 4
sizeof(class H) after adding int 2 virtual 16
My questions:
Why siszeof(A)
is 1 and sizeof(C)
is 1 too ?
Why siszeof(H)
is 16 but sizeof(G)
is 4 ?
Why siszeof(E)
is 16 but sizeof(F)
is 4 ?
Why siszeof(D)
is 8 but sizeof(E)
is 16 ?
My guess:
A virtual function is a pointer with 8 bytes.
But, I do not know why E
size is 16 ?
Adding a function to an empty class does not change its size ?
Any help is appreciated.
thanks
A virtual function is a pointer with 8 bytes.
The use of virtual functions increases the size of an object, typically by the size of a pointer to the vtable. This may be an issue if you wish to create a small object that requires a very large number of instances.
Size of an empty class is not zero. It is 1 byte generally. It is nonzero to ensure that the two different objects will have different addresses.
First off, a virtual function is not a pointer with 8 bytes. In C++ nothing but sizeof(char)
is guaranteed to be any number of bytes.
Second, only the first virtual function in a class increases its size (compiler-dependent, but on most - if not all - it's like this). All subsequent methods do not. Non-virtual functions do not affect the class's size.
This happens because a class instance doesn't hold pointers to methods themselves, but to a virtual function table, which is one per class.
So if you had:
class A
{
virtual void foo();
}
and
class B
{
virtual void goo();
virtual void test();
static void m();
void x();
}
you would have sizeof(A) == sizeof(B)
.
And now:
Why siszeof(A) is 1 and sizeof(C) is 1 too ?
A
and C
have size 1 just because it's not allowed for a class to be of size 0. The functions have nothing to do with it. It's just a dummy byte.
Why siszeof(H) is 16 but sizeof(G) is 4 ?
G
has only one member that accounts for memory - the int
. And on your platform, sizeof(int) == 4
. H
, besides the int
, also has a pointer to the vftable
(virtual function table, see above). The size of this, size of int and allignment are compiler specific.
Why siszeof(E) is 16 but sizeof(F) is 4 ?
Explained above - non virtual methods don't take up memory in the class.
Why siszeof(D) is 8 but sizeof(E) is 16 ?
D
only contains the vftable
pointer which is apparently 8 bytes on your platform. E
also has an int, and the vftable
is aligned to 8 bytes. So it's something like:
class E
4 bytes for int | 4 padding bytes | 8 bytes for vftable pointer |
| x | x | x | x | | | | | v | v | v | v | v | v | v | v |
Why siszeof(A) is 1 and sizeof(C) is 1 too ?
The function in C
is not virtual, so the class doesn't need a vtable pointer, so it needs no more storage than A
. Neither A
nor C
need any storage at all, but because language requires that different instances of the same class have different pointers, they can't have a size of zero - so the compiler makes them as small as it can, i.e. 1 byte.
Why siszeof(H) is 16 but sizeof(G) is 4 ?
G
has no virtual functions, so all it needs to store is the int, which on your compiler and architecture is 4 bytes.
H
has virtual functions, so the class needs to contain an int
and a vtable pointer. All widely used compilers store the vtable pointer at the start of the class, so the layout is {vptr, int}, which is 8+4=12 bytes if you're on a 64 bit host.
However, the compiler is free to pad this out to 16 bytes so that if multiple instances of H
are allocated in an array then all of them will be word-aligned. This is important because there are significant performance implications for accessing a pointer (i.e. the vtable pointer here) if it is not word-aligned.
Why siszeof(E) is 16 but sizeof(F) is 4 ?
E has virtual functions, so needs a vtable ptr, so its layout is just like H
's. F
has no virtual functions, it only has an int, so its layout is just like G
's. so the answer's the same as for G
and H
.
The ordering of the members/functions just doesn't matter here because there's only one member variable and the vtable ptr always goes first if there is one.
Why siszeof(D) is 8 but sizeof(E) is 16 ?
D
has no member variables, but it has a virtual function, so it needs a vtable pointer. The vtable pointer is the only thing it needs, so its size is sizeof(void*)
, which is 8 bytes. E
needs the same as D
, plus 4 bytes for an integer, and the compiler rounds it up to 16 bytes for alignment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With