You might store additional information just before the returned memory address
#include <iostream>
#include <type_traits>
class Pool {
public:
static void* Alloc(std::size_t size) { return data; }
static void Dealloc(void*) {}
private:
static char data[1024];
};
char Pool::data[1024];
class Client
{
public:
void* operator new(size_t size, Pool& pool);
void operator delete(void* memory);
};
struct MemoryHeader {
Pool* pool;
};
void* Client::operator new(size_t size, Pool& pool)
{
auto header = static_cast<MemoryHeader*>(pool.Alloc(sizeof(MemoryHeader) + size));
std::cout << " New Header: " << header << '\n';
header->pool = &pool;
return header + 1;
}
void Client::operator delete(void* memory)
{
auto header = static_cast<MemoryHeader*>(memory) - 1;
std::cout << " Delete Header: " << header << '\n';
header->pool->Dealloc(header);
}
int main()
{
Pool pool;
Client* p = new(pool) Client;
std::cout << "Client Pointer: " << p << '\n';
delete p;
return 0;
}