I've recently discovered Curiously Recurring Template Pattern and started experimenting with it. It turns out that some of the objects created with these classes take more space in the memory than they actually need.
Here's a sample code:
#include <iostream>
struct _Base {
void* ptr;
_Base();
};
_Base::_Base(): ptr(nullptr) {}
template<typename T>
struct Base: public _Base {
private:
Base();
friend T;
};
template<typename T>
Base<T>::Base(): _Base() {}
struct Derived: public Base<Derived> {
int i;
Derived(int i = 0);
};
Derived::Derived(int i): Base<Derived>(), i(i) {}
int main() {
Derived d;
std::cout << "sizeof(_Base): " << sizeof(_Base) << '\n';
std::cout << "sizeof(Base<Derived>): " << sizeof(Base<Derived>) << '\n';
std::cout << "sizeof(Derived): " << sizeof(Derived) << '\n';
std::cout << "sizeof(int) + sizeof(Base<Derived>): " << sizeof(int) + sizeof(Base<Derived>) << '\n';
return 0;
}
This is the output that I got (I compiled it with gcc and Visual Studio compiler and the output is the same):
sizeof(_Base): 8
sizeof(Base<Derived>): 8
sizeof(Derived): 16
sizeof(int) + sizeof(Base<Derived>): 12
_Base
class has a field of type void*
so it should take 8 bites of memory (and it does indeed). Base
class has no new fields added, so the size doesn't change. But when we take a look at Derived
class, its size should be equal to 12 (int typically takes 4 bites and pointers take 8 bites). But the output says, it's actually equal to 16.
My question is: Does the cpp standard allow objects to take more space than needed (presumably for optimization and easier memory management purposes)? Or is it just a bug in my code that I've missed?