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.
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.
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
.
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?
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