The size of an object (i.e. instance of a class) is fixed and known at compile-time. That's why sizeof works.
The same applies to structs, except when a "flexible array member" is used, as well as with arrays.
(note: when used with an array, sizeof returns its total size, in bytes)
You do not have to actually allocate an object to know how much memory an instance of a class would take!
sizeof(f) and sizeof(Foo), where f is a variable of class/struct Foo, are effectively the same.
sizeof operator
When applied to a class type, the result is the number of bytes occupied by a complete object of that class, including any additional padding required to place such object in an array. The number of bytes occupied by a potentially-overlapping subobject may be less than the size of that object.
The result of sizeof is always nonzero, even if applied to an empty class type.
The memory space is allocated to the data members of a class only when an object of the class is declared, and not when the data members are declared inside the class.
So my main question is:
Why does sizeof(Base) 4?
I didn't create an instance of the Base class and expected the compiler doesn't allocate memory for Base.
Please see the following code:
1 2
cout << sizeof(Base) << endl; // 4 without create object
cout << sizeof(emptyClass) << endl; // 1 without create object
The size of an object (i.e. instance of a class) is fixed and known at compile-time. That's why sizeof works.
The same applies to structs, except when a "flexible array member" is used, as well as with arrays.
The size of those things are fixed and known too. The flexible array member just lets you get away with accessing elements beyond the declared size of the struct without directly invoking UB.
Yes, I know. It's just important to be aware that, when it comes to structs with "flexible array member", then sizeof() gives you the fixed size of the struct disregarding the "flexible" member. The actual size of the struct (memory block), as allocated by malloc()at runtime, can be (and usually is) larger than that.
That "flexible array member" is not in C++ Standard, is it? Lets leave such scary VLA's to C.
When compiler compiles code that must allocate memory for object, it must be able to generate the correct instructions -- how many bytes to allocate.
1 2 3 4 5 6
class Base
{
public:
void Print();
int a;
};
is a definition of a type named "Base". Compiler can calculate from that definition how many bytes to allocate for an object of type Base. The size is at least the sum of sizes of all members. Here is member of type int and compiler has size for it. The sizeof merely returns the result of that calculation.
Declaration of a member variable within class definition is not quite same as declaration of variable within function. Class definition is mere description of what could be.
1 2 3 4 5 6 7 8 9
struct Sample
{
double x;
double y;
};
int main() {
int z;
}
The executable of program above is practically identical with code below because the program does not use any Sample objects.
1 2 3
int main() {
int z;
}
The following program will allocate memory for one int, two double and perhaps some padding too:
1 2 3 4 5 6 7 8 9 10
struct Sample
{
double x;
double y;
};
int main() {
int z;
Sample w;
}
This translation unit does not need to know the size of type Sample, because it only has pointers:
1 2 3 4 5 6 7
struct Sample;
void func( Sample* );
int main() {
Sample* w = nullptr;
func( w );
}