Last active
May 26, 2023 15:55
-
-
Save jalotra/55085e7ad1ce1f1fdef6dea2040cbe8a to your computer and use it in GitHub Desktop.
This file contains 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
#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