0

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?

  • 3
    `_Base` That identifier is reserved to the language implementation. You should give the class another name. – eerorika Jun 25 '20 at 21:03
  • 3
    This has nothing to do with CRTP. You can re-create this example with plain classes and get the exact same result. And there is a duplicate of this somewhere – StoryTeller - Unslander Monica Jun 25 '20 at 21:04
  • @StoryTeller-UnslanderMonica Already tagged. – cdhowie Jun 25 '20 at 21:06
  • Expanding on eerorika's comment: [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301 Jun 25 '20 at 21:06
  • 1
    Answering the OP's title question: yes, C++ objects can take more memory *than necessary*. For example, compilers are allowed to insert padding between data members. There is no specification as to how much memory. C++ objects can also have space at the end of the object (some objects may have an unused "virtual table"). – Thomas Matthews Jun 25 '20 at 21:13

0 Answers0