Created
August 13, 2023 13:57
-
-
Save diffstorm/dbed8028ee4f8e80984cf42d78ddf33a to your computer and use it in GitHub Desktop.
Static memory allocator for embedded systems in C with auto fragmentation where malloc is unwanted
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
/* | |
Static memory allocator for embedded systems in C with auto fragmentation where malloc is unwanted | |
Author : Eray Ozturk | [email protected] | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stddef.h> | |
struct BlockHeader { | |
size_t size; | |
struct BlockHeader* next; | |
}; | |
typedef struct { | |
char* buffer; | |
size_t bufferSize; | |
struct BlockHeader* head; | |
} StaticMemoryAllocator; | |
void initializeAllocator(StaticMemoryAllocator* allocator, char* buffer, size_t bufferSize) { | |
allocator->buffer = buffer; | |
allocator->bufferSize = bufferSize; | |
allocator->head = (struct BlockHeader*)buffer; | |
allocator->head->size = bufferSize - sizeof(struct BlockHeader); | |
allocator->head->next = NULL; | |
} | |
void* allocate(StaticMemoryAllocator* allocator, size_t size) { | |
if (size == 0 || size > allocator->bufferSize) { | |
return NULL; // Invalid size | |
} | |
struct BlockHeader* prev = NULL; | |
struct BlockHeader* curr = allocator->head; | |
while (curr) { | |
if (curr->size >= size) { | |
// Allocate from the current block | |
if (curr->size > size + sizeof(struct BlockHeader)) { | |
// Split the block | |
struct BlockHeader* newBlock = (struct BlockHeader*)((char*)curr + sizeof(struct BlockHeader) + size); | |
newBlock->size = curr->size - size - sizeof(struct BlockHeader); | |
newBlock->next = curr->next; | |
curr->size = size; | |
curr->next = newBlock; | |
} | |
// Update the free list | |
if (prev) { | |
prev->next = curr->next; | |
} else { | |
allocator->head = curr->next; | |
} | |
return (char*)curr + sizeof(struct BlockHeader); | |
} | |
prev = curr; | |
curr = curr->next; | |
} | |
return NULL; // Not enough memory | |
} | |
void deallocate(StaticMemoryAllocator* allocator, void* ptr) { | |
if (ptr >= allocator->buffer && ptr < allocator->buffer + allocator->bufferSize) { | |
struct BlockHeader* block = (struct BlockHeader*)((char*)ptr - sizeof(struct BlockHeader)); | |
block->next = allocator->head; | |
allocator->head = block; | |
} | |
} | |
void cleanupAllocator(StaticMemoryAllocator* allocator) { | |
struct BlockHeader* curr = allocator->head; | |
while (curr) { | |
curr->size = 0; | |
curr->next = NULL; | |
curr = curr->next; | |
} | |
} | |
int main() { | |
size_t bufferSize = 1024; | |
char memoryBuffer[1024]; | |
StaticMemoryAllocator memoryAllocator; | |
initializeAllocator(&memoryAllocator, memoryBuffer, bufferSize); | |
// Allocate an int | |
int* intPtr = (int*)allocate(&memoryAllocator, sizeof(int)); | |
if (intPtr) { | |
*intPtr = 42; | |
printf("Allocated int: %d\n", *intPtr); | |
} else { | |
printf("Memory allocation failed\n"); | |
} | |
// Allocate a double block | |
double* doublePtr = (double*)allocate(&memoryAllocator, sizeof(double)); | |
if (doublePtr) { | |
*doublePtr = 3.14; | |
printf("Allocated double: %.2lf\n", *doublePtr); | |
} else { | |
printf("Memory allocation failed\n"); | |
} | |
// Deallocate the int block | |
if (intPtr) { | |
deallocate(&memoryAllocator, intPtr); | |
intPtr = NULL; | |
printf("Deallocated int\n"); | |
} | |
// Allocate a larger block | |
char* charPtr = (char*)allocate(&memoryAllocator, 256); | |
if (charPtr) { | |
printf("Allocated 256 bytes\n"); | |
} else { | |
printf("Memory allocation failed\n"); | |
} | |
// Clean up the allocator (release all memory) | |
cleanupAllocator(&memoryAllocator); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment