DEV Community

Jonah Goldsmith
Jonah Goldsmith

Posted on • Originally published at jonahmgoldsmith.hashnode.dev on

Custom Memory Allocation With C++ Objects

So, recently as I have gotten more and more obsessed with creating a game engine I have been battling with myself over something. C or C++? Besides the fact that I hate OOP or object-oriented programming and the fact that modern C++ is complicated and scary, there was another HUGE reason I did not want to make my codebase C++ focused. Memory management of Classes/Objects! While creating my projects in C, I have always created a sort of memory subsystem that controls how I allocate memory. But whenever I venture into C++ I get stuck! How am I supposed to control memory allocation if my objects need to call their constructor with the "new" operator/keyword? Well, after doing more research and learning more about C++ I learned it is not so hard after all. All we need is everyone's favorite thing... Template Metaprogramming! If you can't tell, I am not a fan of templates. But maybe they do come in handy for a few things. Let's jump into some code:

template <typename T, typename... Args>
T* memcreate(Args... arg)
{
    void* memory = malloc(sizeof(T));
    T* mem = new(memory)T(arg...);
    return mem;
}

struct testing
    {
    public:
        testing(int num, const char* word) {x = num; name = (char*)word;}
        ~testing() = default;
        int x;
        char* name;
    };

//USAGE:
testing* test = memcreate<testing>(10, "charles");

Enter fullscreen mode Exit fullscreen mode

And would you look at that! Now we can use malloc(or better yet a custom allocator) and instantiate C++ objects without the new keyword! If you look closely you will see that we still use the "new" keyword in the template function. This version of the keyword is called "placement new" and is used to "place" the memory we allocate from one object onto another while also "instantiating" the object and calling its constructor. I am sure there is a more technical way to explain it but that's what I am going with! Oh and if you are wondering our delete function would look like this:

template <typename T>
void memdelete(T* ptr)
{
    ptr->~T();
    free(ptr);
}

Enter fullscreen mode Exit fullscreen mode

Very, very, simple. Next Post I will try to go into more detail about why this is useful and how I can track memory allocations, and use things like custom allocators to have more performant allocations! Thanks for reading! Go Code!

Top comments (0)