So I am making a Memory Stack Allocator that is capable of allocating any instance of any type onto the heap in a continuous fashion.
In order to do this i have added a 'AllocationHeader' class directly before each allocation which contains a void* to the instance address itself and a AllocationHeader* to the previous header. So far this has worked perfectly and i'm able to allocate and deallocate etc.
But i've ran into 1 (possibly 2) problems. In order to deallocate properly I also need to call the destructor of the object in question and then remove it from the stack. This is fine when i'm removing an instance that i have a pointer to as i can just pass it to the deallocate function and it knows what type it is and does its thing.
The problem lies when I want to create functions like deallocateAll() or deallocateAllAboveObject(T* obj) as I would need to know the types of each allocation without explicitly passing their pointer, so i could go down each allocation in the stack calling the deconstructor on each as I go.
What I would like is to be able to create an AllocationHeader which can store a pointer of any type, and then the type of the pointer can be retrieved at a later date without already knowing the type.
I'm really not sure how to do this as all suggestions that i've seen so far involve comparing the object with a specific type and seeing if they're the same. However I can't just check against each possible class in the program as there could be 1000's as I continue to build on this.
Alternatively if you have any suggestions for an alternative approach to a stack allocator that can deal with any type, that would be great as well.
Any help at all would be greatly appreciated.
Due to C++'s static type system, I can only see a couple of solutions to the problem
struct destructible { virtual ~destructible() { } }
, however this will potentially enlarge & alter the layout of any types you alter to derive from this.Or uppon allocation store a function object that does the destruction, e.g. using the following template
template<typename T> void destroy(void* p) { reinterpret_cast<T*>(p)->T::~T(); }
struct AllocationHeader
{
template<typename T> AllocationHeader(AllocationHeader* previouse, void* data)
: previouse(previouse), data(data), destructor(&destroy<T>) { }
AllocationHeader* previouse;
void* data;
void (*destructor)(void*);
}
void deallocateAll(AllocationHeader& start)
{
for (AllocationHeader* a = &start; a != nullptr; a = start->previouse;)
{
a->destructor(a->data);
delete a->data;
}
}
(Without providing your code for the AllocationHeader
type it is difficuilt to help you.)
Note: My compiler/IDE is currently reinstalling so I am unable to test the above code, I am pretty sure about most of it, except I may need to put a typename
in the destructor call syntax reinterpret_cast<T*>(p).T::~T();
EDIT Using a template constructor, where the template arguments cannot be inferred is a bad idea, the following constructor should be used instead
AllocationHeader(AllocationHeader* previouse, void* data, void(*destructor)(void*))
: previouse(previouse), data(data), destructor(destructor) { }
Just pass &destroy<T>
as the 3rd argument to it.