From 09821002b314b7c8517f16d351b1c6b1088a47dc Mon Sep 17 00:00:00 2001 From: pommicket Date: Mon, 15 Sep 2025 20:59:38 -0400 Subject: Better examples --- examples/custom_alloc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 examples/custom_alloc.c (limited to 'examples/custom_alloc.c') diff --git a/examples/custom_alloc.c b/examples/custom_alloc.c new file mode 100644 index 0000000..42843ce --- /dev/null +++ b/examples/custom_alloc.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include + +// Custom memory allocation functions +typedef struct { + uint64_t allocations, frees; + size_t memory_used; + alignas(max_align_t) char memory[100000]; +} Memory; +static void *my_calloc(void *udata, size_t nmemb, size_t sz) { + Memory *my_memory = udata; + char *mem = (char *)my_memory->memory + my_memory->memory_used; + size_t new_memory_used = my_memory->memory_used; + while ((uintptr_t)mem & 7) + mem++, new_memory_used++; + new_memory_used += 8 + nmemb * sz; + if (new_memory_used > sizeof my_memory->memory) { + // out of memory: return NULL + return NULL; + } + my_memory->allocations++; + my_memory->memory_used = new_memory_used; + // store size of allocation + *(uint64_t *)mem = nmemb * sz; + return mem + sizeof (uint64_t); +} +static void my_free(void *udata, void *ptr) { + if (!ptr) { + // free must do nothing when null pointer is passed + return; + } + Memory *my_memory = udata; + my_memory->frees++; +} + +static void *my_realloc(void *udata, void *ptr, size_t new_size) { + if (!ptr) { + // realloc(ptr = NULL) is equivalent to malloc + return my_calloc(udata, new_size, 1); + } + // inefficient but correct realloc implementation: + // just free the old memory and allocate brand new memory + size_t old_size = ((uint64_t *)ptr)[-1]; + void *new_ptr = my_calloc(udata, new_size, 1); + if (!new_ptr) { + // out-of-memory: return NULL + return NULL; + } + memcpy(new_ptr, ptr, old_size); + my_free(udata, ptr); + return new_ptr; +} + +int main(void) { + pom_error *error; + pom_settings settings = {0}; + // set allocation functions + settings.calloc = my_calloc; + settings.realloc = my_realloc; + settings.free = my_free; + static Memory my_memory; + // set udata pointer which is passed to the functions + settings.allocator_udata = &my_memory; + + pom_conf *conf = pom_load_string(&settings, "conf.pom", + "foo = bar\n" + "[core]\n" + "list = 1,6,78,9\n", + &error); + if (!conf) { + pom_error_print(error); + // error must be freed with custom allocation function + my_free(&my_memory, error); + return EXIT_FAILURE; + } + char **list = pom_conf_get_list(conf, "core.list"); + for (size_t i = 0; list[i]; i++) + printf("- %s\n",list[i]); + // lists must be freed with custom allocation function + my_free(&my_memory, list); + pom_conf_free(conf); + if (my_memory.allocations != my_memory.frees) { + // if this ever happens, it's a bug in libpom + fprintf(stderr, "libpom is leaking memory!!!\n"); + return EXIT_FAILURE; + } + return 0; +} -- cgit v1.2.3