Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstddef> // For size_t
- // Structure for each memory block
- struct Block {
- size_t size; // Size of this block (excluding header)
- bool free; // Is this block free?
- Block* next; // Pointer to the next block
- };
- class SimpleAllocator {
- private:
- void* pool; // The big memory pool we manage
- Block* head; // Start of our block list
- size_t totalSize; // Total size of the pool
- public:
- // Initialize the allocator with a fixed pool size
- SimpleAllocator(size_t size) : totalSize(size) {
- pool = malloc(size); // Get the raw memory from the system
- if (!pool) {
- throw std::bad_alloc();
- }
- // Set up the first block (whole pool is free initially)
- head = static_cast<Block*>(pool);
- head->size = size - sizeof(Block); // Account for header size
- head->free = true;
- head->next = nullptr;
- }
- // Clean up
- ~SimpleAllocator() {
- free(pool); // Release the pool back to the system
- }
- // Allocate memory
- void* allocate(size_t size) {
- // Find a free block big enough
- Block* current = head;
- Block* best = nullptr;
- while (current) {
- if (current->free && current->size >= size) {
- best = current; // First-fit strategy (could use best-fit)
- break;
- }
- current = current->next;
- }
- if (!best) {
- return nullptr; // No suitable block found
- }
- // Split the block if it’s too big
- if (best->size >= size + sizeof(Block) + 1) {
- Block* newBlock = reinterpret_cast<Block*>(
- reinterpret_cast<char*>(best) + sizeof(Block) + size
- );
- newBlock->size = best->size - size - sizeof(Block);
- newBlock->free = true;
- newBlock->next = best->next;
- best->size = size;
- best->next = newBlock;
- }
- best->free = false; // Mark as used
- return reinterpret_cast<char*>(best) + sizeof(Block); // Return pointer after header
- }
- // Deallocate memory
- void deallocate(void* ptr) {
- if (!ptr) return;
- // Find the block (ptr is after the header)
- Block* block = reinterpret_cast<Block*>(
- static_cast<char*>(ptr) - sizeof(Block)
- );
- block->free = true; // Mark it free
- // Merge with next block if it’s free
- if (block->next && block->next->free) {
- block->size += sizeof(Block) + block->next->size;
- block->next = block->next->next;
- }
- // Merge with previous block if it’s free
- Block* prev = head;
- while (prev && prev->next != block) {
- prev = prev->next;
- }
- if (prev && prev->free) {
- prev->size += sizeof(Block) + block->size;
- prev->next = block->next;
- }
- }
- };
- int main() {
- // Create an allocator with 1024 bytes
- SimpleAllocator alloc(1024);
- // Allocate some memory
- int* num1 = static_cast<int*>(alloc.allocate(5 * sizeof(int)));
- if (num1) {
- for (int i = 0; i < 5; i++) {
- num1[i] = i + 1;
- }
- for (int i = 0; i < 5; i++) {
- std::cout << num1[i] << " "; // Prints 1 2 3 4 5
- }
- std::cout << "\n";
- }
- // Free it
- alloc.deallocate(num1);
- // Allocate again to test reuse
- int* num2 = static_cast<int*>(alloc.allocate(3 * sizeof(int)));
- if (num2) {
- num2[0] = 10;
- num2[1] = 20;
- num2[2] = 30;
- std::cout << num2[0] << " " << num2[1] << " " << num2[2] << "\n"; // Prints 10 20 30
- alloc.deallocate(num2);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement