Generically overloading operator new while considering alignment requirements

徘徊边缘 提交于 2020-01-14 03:23:07

问题


Situation

I am writing a memory manager for dynamic memory (de)allocations. For a class A to use it when operator new (or delete) is called, it is sufficient for class A to inherit from a class CustomAllocate, which itself overloads new and delete in a way that uses the memory manager.

Problem

However, apparently I completely missed out on alignment requirements. Unfortunately, CustomAllocate::new has no information about how a class A inheriting from it should be aligned as the only parameter is the size of the requested memory. I am searching for a way to include alignment information without having to overload new (and delete) in every class A to use the memory manager.

Idea 1 (and why it does not work)

Templating class CustomAllocate with an integer value representing the alignment requirements and inheriting like so: class A : public CustomAllocate< alignof(A) >.

Impossible because alignof(A) cannot be known at the time it has to be passed as template parameter, even though the passed parameter should never change the alignment requirements of class A.

Idea 2 (and why it does not work)

Having a pure virtual function virtual int CustomAllocate::getAlignment() = 0 that is implemented in every class A by copy pasting something like return alignof(A);.

Impossible because new is static and thus can never access a virtual function.


Any working ideas?


回答1:


Somewhat to my surprise, the following seems to work:

template <typename T> class CustomAllocate
{
public:
    void* operator new (std::size_t count)
    {
        std::cout << "Calling new, aligment = " << alignof (T) << "\n";
        return aligned_alloc (alignof (T), count);
    }

    void operator delete (void *p)
    {
        std::cout << "Calling delete\n";
        free (p);
    }
};

Test program:

class A : public CustomAllocate <A>
{
public:
    A (int a, int b) : a (a), b (b) { }
    int a, b;
};

int main ()
{
    A *x = new A (1, 2);
    std::cout << x->a << ", " << x->b << "\n";
    delete x;
}

Output:

Calling new, aligment = 4
1, 2
Calling delete

Live Demo



来源:https://stackoverflow.com/questions/53178405/generically-overloading-operator-new-while-considering-alignment-requirements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!