Skip to content

Instantly share code, notes, and snippets.

@jalotra
Last active May 26, 2023 15:55
Show Gist options
  • Save jalotra/55085e7ad1ce1f1fdef6dea2040cbe8a to your computer and use it in GitHub Desktop.
Save jalotra/55085e7ad1ce1f1fdef6dea2040cbe8a to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
size_t size;
struct Node* next;
} Node;
typedef struct {
void* pool_start;
size_t pool_size;
Node* free_list;
} MemoryPool;
void initializeMemoryPool(MemoryPool* pool, size_t size) {
pool->pool_start = malloc(size);
pool->pool_size = size;
Node* initial_block = (Node*)pool->pool_start;
initial_block->size = size - sizeof(Node);
initial_block->next = NULL;
pool->free_list = initial_block;
}
void* allocateMemory(MemoryPool* pool, size_t size) {
// Find a suitable free block
Node* prev = NULL;
Node* curr = pool->free_list;
while (curr) {
if (curr->size >= size) {
break; // Found a block with sufficient size
}
prev = curr;
curr = curr->next;
}
if (!curr) {
return NULL; // No suitable free block found
}
// Allocate from the found block
if (curr->size >= size + sizeof(Node)) {
// Split the block if there is enough remaining space
Node* new_block = (Node*)((char*)curr + sizeof(Node) + size);
new_block->size = curr->size - size - sizeof(Node);
new_block->next = curr->next;
curr->size = size;
curr->next = new_block;
}
// Remove the allocated block from the free list
if (prev) {
prev->next = curr->next;
} else {
pool->free_list = curr->next;
}
return (char*)curr + sizeof(Node);
}
void freeMemory(MemoryPool* pool, void* ptr) {
if (!ptr) {
return; // Null pointer, nothing to free
}
// Find the block corresponding to the given pointer
Node* freed_block = (Node*)((char*)ptr - sizeof(Node));
// Insert the freed block into the free list
Node* prev = NULL;
Node* curr = pool->free_list;
while (curr && curr < freed_block) {
prev = curr;
curr = curr->next;
}
if (prev) {
prev->next = freed_block;
} else {
pool->free_list = freed_block;
}
freed_block->next = curr;
// Coalesce adjacent free blocks
if (curr && (char*)freed_block + freed_block->size + sizeof(Node) == (char*)curr) {
freed_block->size += curr->size + sizeof(Node);
freed_block->next = curr->next;
}
if (prev && (char*)prev + prev->size + sizeof(Node) == (char*)freed_block) {
prev->size += freed_block->size + sizeof(Node);
prev->next = freed_block->next;
}
}
void destroyMemoryPool(MemoryPool* pool) {
free(pool->pool_start);
pool->pool_start = NULL;
pool->pool_size = 0;
pool->free_list = NULL;
}
int main() {
MemoryPool pool;
initializeMemoryPool(&pool, 1024);
void* ptr1 = allocateMemory(&pool, 256);
void* ptr2 = allocateMemory(&pool, 512);
if (ptr1 && ptr2) {
printf("Memory allocated successfully!\n");
printf("Pointer 1: %p\n", ptr1);
printf("Pointer 2: %p\n", ptr2);
freeMemory(&pool, ptr1);
freeMemory(&pool, ptr2);
printf("Memory freed successfully!\n");
} else {
printf("Failed to allocate memory.\n");
}
destroyMemoryPool(&pool);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment