This is what I have currently
#include <cstddef>
#include <iostream>
#include <memory>
class Region {
public:
Region(size_t size_) : size(size_), memory(new char[size_]), offset(0) {}
static Region *createRegion(size_t size) { return new Region(size); }
void *allocate(size_t alignment, size_t offset_) {
if (offset + offset_ > size) {
grow(size);
}
void *currentPtr = memory + offset;
void *alignedPtr = std::align(alignment, offset_, currentPtr, size);
if (!alignedPtr) {
throw std::runtime_error("Out of memory or alignment issues!");
}
// add padding based on alignment to the offset
std::size_t padding = static_cast<char *>(alignedPtr) - (memory + offset);
offset += padding + offset_;
return memory + offset;
}
void grow(size_t offset_) {
size_t newSize = std::max(size * 2, size + offset_);
char *NewMemory = new char[newSize];
std::copy(memory, memory + offset, NewMemory);
delete[] memory;
memory = NewMemory;
size = newSize;
}
~Region() { delete[] memory; }
private:
char *memory;
size_t offset;
size_t size;
};
struct Node {
int a;
Node(int a_) : a(a_) {}
};
int main() {
Region *r1 = Region::createRegion(sizeof(Node) * 3);
Node *n1 = new (r1->allocate(sizeof(Node), alignof(Node))) Node(1);
Node *n2 = new (r1->allocate(sizeof(Node), alignof(Node))) Node(2);
Node *n3 = new (r1->allocate(sizeof(Node), alignof(Node))) Node(3);
Node *n4 = new (r1->allocate(sizeof(Node), alignof(Node))) Node(4);
// is it properly constructed & allocated?
std::cout << n1->a;
std::cout << n2->a;
std::cout << n3->a;
std::cout << n4->a;
delete r1;
return 0;
}
Everything works fine until I need to grow the arena, and as a consequence, the whole memory block gets messed up(I assume). Getting rid of n4 makes it correct again.
What can I improve on this arena allocator?