Sat, 25 Jan 2025 13:44:24 +0100
add marker to every incomplete page
relates to #451
# Memory Pool <warning> Outdated - Rewrite! </warning> A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. It also allows you to register destructor functions for the allocated memory, which are automatically called before the memory is deallocated. Additionally, you may also register _independent_ destructor functions within a pool in case some external library allocated memory for you, which should be freed together with this pool. Many UCX features support the use of an allocator. The [strings](string.h.md), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with just a single call to `cxMempoolFree()`. The following code illustrates this on the example of reading a CSV file into memory. ```C #include <stdio.h> #include <cx/mempool.h> #include <cx/linked_list.h> #include <cx/string.h> #include <cx/buffer.h> #include <cx/utils.h> typedef struct { cxstring column_a; cxstring column_b; cxstring column_c; } CSVData; int main(void) { CxMempool* pool = cxBasicMempoolCreate(128); FILE *f = fopen("test.csv", "r"); if (!f) { perror("Cannot open file"); return 1; } // close the file automatically at pool destruction cxMempoolRegister(pool, f, (cx_destructor_func) fclose); // create a buffer using the memory pool for destruction CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); // read the file into the buffer and turn it into a string cx_stream_copy(f, content, (cx_read_func) fread, cxBufferWriteFunc); fclose(f); cxstring contentstr = cx_strn(content->space, content->size); // split the string into lines - use the mempool for allocating the target array cxstring* lines; size_t lc = cx_strsplit_a(pool->allocator, contentstr, CX_STR("\n"), SIZE_MAX, &lines); // skip the header and parse the remaining data into a linked list // the nodes of the linked list shall also be allocated by the mempool CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); for (size_t i = 1 ; i < lc ; i++) { if (lines[i].length == 0) continue; cxstring fields[3]; size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); if (fc != 3) { fprintf(stderr, "Syntax error in line %zu.\n", i); cxMempoolFree(pool); return 1; } CSVData data; data.column_a = fields[0]; data.column_b = fields[1]; data.column_c = fields[2]; cxListAdd(datalist, &data); } // iterate through the list and output the data CxIterator iter = cxListIterator(datalist); cx_foreach(CSVData*, data, iter) { printf("Column A: %.*s | " "Column B: %.*s | " "Column C: %.*s\n", (int)data->column_a.length, data->column_a.ptr, (int)data->column_b.length, data->column_b.ptr, (int)data->column_c.length, data->column_c.ptr ); } // cleanup everything, no manual free() needed cxMempoolFree(pool); return 0; } ``` ## Undocumented Symbols (TODO) ### cxMempoolCreate ### cxMempoolFree ### cxMempoolRegister ### cxMempoolRemoveDestructor ### cxMempoolSetDestructor