Added custom allocator support

This commit is contained in:
2022-11-19 08:18:45 +00:00
parent 0b57f7efe7
commit 4518b59417
4 changed files with 75 additions and 9 deletions

View File

@@ -5,7 +5,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void* reallocate(void* pointer, size_t oldSize, size_t newSize) { //default allocator
void* defaultAllocator(void* pointer, size_t oldSize, size_t newSize) {
if (newSize == 0 && oldSize == 0) { if (newSize == 0 && oldSize == 0) {
//causes issues, so just skip out with a NO-OP //causes issues, so just skip out with a NO-OP
return NULL; return NULL;
@@ -20,10 +21,30 @@ void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
void* mem = realloc(pointer, newSize); void* mem = realloc(pointer, newSize);
if (mem == NULL) { if (mem == NULL) {
fprintf(stderr, ERROR "[internal]Memory allocation error (requested %d for %ld, replacing %d)\n" ERROR, (int)newSize, (long int)pointer, (int)oldSize); fprintf(stderr, ERROR "[internal] Memory allocation error (requested %d for %ld, replacing %d)\n" RESET, (int)newSize, (long int)pointer, (int)oldSize);
exit(-1); exit(-1);
} }
return mem; return mem;
} }
//exposed API
static AllocatorFn allocator = defaultAllocator;
void setAllocator(AllocatorFn fn) {
if (fn == NULL) {
fprintf(stderr, ERROR "[internal] Memory allocator error (can't be null)\n" RESET);
exit(-1);
}
if (fn == reallocate) {
fprintf(stderr, ERROR "[internal] Memory allocator error (can't loop the reallocate function)\n" RESET);
exit(-1);
}
allocator = fn;
}
void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
return allocator(pointer, oldSize, newSize);
}

View File

@@ -10,5 +10,8 @@
#define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
#define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0) #define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
void* reallocate(void* pointer, size_t oldSize, size_t newSize); //implementation details
typedef void* (*AllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
void setAllocator(AllocatorFn);
void* reallocate(void* pointer, size_t oldSize, size_t newSize);

View File

@@ -6,7 +6,7 @@
#define TOY_VERSION_MAJOR 0 #define TOY_VERSION_MAJOR 0
#define TOY_VERSION_MINOR 6 #define TOY_VERSION_MINOR 6
#define TOY_VERSION_PATCH 2 #define TOY_VERSION_PATCH 3
#define TOY_VERSION_BUILD __DATE__ " " __TIME__ #define TOY_VERSION_BUILD __DATE__ " " __TIME__
//platform exports/imports //platform exports/imports

View File

@@ -3,32 +3,74 @@
#include "console_colors.h" #include "console_colors.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
int main() { //the test allocator
static int callCount = 0;
void* allocator(void* pointer, size_t oldSize, size_t newSize) {
callCount++;
if (newSize == 0 && oldSize == 0) {
return NULL;
}
if (newSize == 0) {
free(pointer);
return NULL;
}
void* mem = realloc(pointer, newSize);
if (mem == NULL) {
exit(-1);
}
return mem;
}
void testMemoryAllocation() {
{ {
//test single pointer //test single pointer
int* integer = ALLOCATE(int, 1); int* integer = ALLOCATE(int, 1);
FREE(int, integer); FREE(int, integer);
} }
{ {
//test single pointer //test single pointer array
int* array = ALLOCATE(int, 10); int* array = ALLOCATE(int, 10);
array[1] = 42; //access the given memory
FREE_ARRAY(int, array, 10); FREE_ARRAY(int, array, 10);
} }
{ {
//test single pointer //test multiple pointer arrays
int* array1 = ALLOCATE(int, 10); int* array1 = ALLOCATE(int, 10);
int* array2 = ALLOCATE(int, 10); int* array2 = ALLOCATE(int, 10);
array1[1] = 42; //access the given memory
array2[1] = 42; //access the given memory
FREE_ARRAY(int, array1, 10); FREE_ARRAY(int, array1, 10);
FREE_ARRAY(int, array2, 10); FREE_ARRAY(int, array2, 10);
} }
}
int main() {
//test the default allocator
testMemoryAllocation();
//test the custom allocator
setAllocator(allocator);
testMemoryAllocation();
if (callCount != 8) {
fprintf(stderr, ERROR "Unexpected call count for custom allocator; was called %d times" RESET, callCount);
return -1;
}
printf(NOTICE "All good\n" RESET); printf(NOTICE "All good\n" RESET);
return 0; return 0;
} }