#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; }