Skip to content

Instantly share code, notes, and snippets.

@victorholt
Created May 26, 2018 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorholt/b80b08c95bd0906ebe521eb6083e4de2 to your computer and use it in GitHub Desktop.
Save victorholt/b80b08c95bd0906ebe521eb6083e4de2 to your computer and use it in GitHub Desktop.
C++ Memory Pool Allocation
// Example program
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <cstring>
#include <assert.h>
using namespace std;
template<typename T>
class ref
{
public:
ref() {
}
~ref() {
}
T data;
void print() {
cout << "Data = " << data << endl;
}
};
class alloc_manager
{
private:
struct mem_block
{
bool is_free;
size_t size;
size_t index;
void* data;
};
vector<mem_block> blocks;
void* pool = nullptr;
size_t mem_block_size = 10;
size_t max_pool_size = 1000;
size_t usage = 0;
size_t mem_index = 0;
public:
alloc_manager()
{
pool = malloc(max_pool_size);
assert((100 % 10) == 0 && "Invalid block sizes!");
for (size_t i = 0; i < mem_block_size; i++) {
mem_block block;
block.data = pool + (i * mem_block_size);
block.index = i;
block.size = 0;
block.is_free = true;
blocks.push_back(block);
}
}
template<typename T>
size_t alloc_ref(size_t size, T*& data)
{
cout << "Attempting to allocat " << size << " space!" << endl;
if ((usage + size) >= max_pool_size) {
cout << "Unable to allocate space!" << endl;
return 0;
}
usage += size;
auto block = find_block(size);
assert(block != nullptr && "Failed to find available memory block!");
data = reinterpret_cast<T*>(block->data);
data = new(block->data) T();
return block->index;
}
template<typename T>
void free_ref(size_t index, T*& data) {
if (data == nullptr) return;
assert(index < blocks.size() && "Invalid memory block access!");
auto* block = &blocks[index];
block->size = 0;
block->is_free = true;
data->~T();
data = nullptr;
}
mem_block* find_block(size_t requested_size) {
for (size_t i = 0; i < mem_block_size; i++) {
auto* block = &blocks[i];
if (!block->is_free) {
continue;
}
block->is_free = false;
memset(pool + (i * mem_block_size), 0, mem_block_size);
return block;
}
return nullptr;
}
};
int main()
{
alloc_manager manager;
ref<int>* i1;
ref<int>* i2;
ref<int>* i3;
auto mi1 = manager.alloc_ref(sizeof(ref<int>), i1);
cout << "Allocated block: " << mi1 << endl;
i1->data = 1;
auto mi2 = manager.alloc_ref(sizeof(ref<int>), i2);
cout << "Allocated block: " << mi2 << endl;
i2->data = 2;
i2->print();
manager.free_ref(mi2, i2);
auto mi3 = manager.alloc_ref(sizeof(ref<int>), i3);
cout << "Allocated block: " << mi3 << endl;
i3->data = 3;
i1->print();
i3->print();
manager.free_ref(mi1, i1);
manager.free_ref(mi3, i3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment