Created
May 26, 2018 18:39
-
-
Save victorholt/b80b08c95bd0906ebe521eb6083e4de2 to your computer and use it in GitHub Desktop.
C++ Memory Pool Allocation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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