Sat, 25 Jan 2025 13:44:24 +0100
add marker to every incomplete page
relates to #451
1143
0559812df10c
assign proper names to the documentation topics
Mike Becker <universe@uap-core.de>
parents:
1142
diff
changeset
|
1 | # Memory Pool |
1141 | 2 | |
1146
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
3 | <warning> |
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
4 | Outdated - Rewrite! |
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
5 | </warning> |
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
6 | |
1141 | 7 | A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. |
8 | It also allows you to register destructor functions for the allocated memory, which are automatically called before | |
9 | the memory is deallocated. | |
10 | Additionally, you may also register _independent_ destructor functions within a pool in case some external library | |
11 | allocated memory for you, which should be freed together with this pool. | |
12 | ||
13 | Many UCX features support the use of an allocator. | |
1142
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
14 | The [strings](string.h.md), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. |
1141 | 15 | You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with |
16 | just a single call to `cxMempoolFree()`. | |
17 | ||
18 | The following code illustrates this on the example of reading a CSV file into memory. | |
19 | ```C | |
20 | #include <stdio.h> | |
21 | #include <cx/mempool.h> | |
22 | #include <cx/linked_list.h> | |
23 | #include <cx/string.h> | |
24 | #include <cx/buffer.h> | |
25 | #include <cx/utils.h> | |
26 | ||
27 | typedef struct { | |
28 | cxstring column_a; | |
29 | cxstring column_b; | |
30 | cxstring column_c; | |
31 | } CSVData; | |
32 | ||
33 | int main(void) { | |
34 | CxMempool* pool = cxBasicMempoolCreate(128); | |
35 | ||
36 | FILE *f = fopen("test.csv", "r"); | |
37 | if (!f) { | |
38 | perror("Cannot open file"); | |
39 | return 1; | |
40 | } | |
41 | // close the file automatically at pool destruction | |
42 | cxMempoolRegister(pool, f, (cx_destructor_func) fclose); | |
43 | ||
44 | // create a buffer using the memory pool for destruction | |
45 | CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); | |
46 | ||
47 | // read the file into the buffer and turn it into a string | |
48 | cx_stream_copy(f, content, (cx_read_func) fread, cxBufferWriteFunc); | |
49 | fclose(f); | |
50 | cxstring contentstr = cx_strn(content->space, content->size); | |
51 | ||
52 | // split the string into lines - use the mempool for allocating the target array | |
53 | cxstring* lines; | |
54 | size_t lc = cx_strsplit_a(pool->allocator, contentstr, | |
55 | CX_STR("\n"), SIZE_MAX, &lines); | |
56 | ||
57 | // skip the header and parse the remaining data into a linked list | |
58 | // the nodes of the linked list shall also be allocated by the mempool | |
59 | CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); | |
60 | for (size_t i = 1 ; i < lc ; i++) { | |
61 | if (lines[i].length == 0) continue; | |
62 | cxstring fields[3]; | |
63 | size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); | |
64 | if (fc != 3) { | |
65 | fprintf(stderr, "Syntax error in line %zu.\n", i); | |
66 | cxMempoolFree(pool); | |
67 | return 1; | |
68 | } | |
69 | CSVData data; | |
70 | data.column_a = fields[0]; | |
71 | data.column_b = fields[1]; | |
72 | data.column_c = fields[2]; | |
73 | cxListAdd(datalist, &data); | |
74 | } | |
75 | ||
76 | // iterate through the list and output the data | |
77 | CxIterator iter = cxListIterator(datalist); | |
78 | cx_foreach(CSVData*, data, iter) { | |
79 | printf("Column A: %.*s | " | |
80 | "Column B: %.*s | " | |
81 | "Column C: %.*s\n", | |
82 | (int)data->column_a.length, data->column_a.ptr, | |
83 | (int)data->column_b.length, data->column_b.ptr, | |
84 | (int)data->column_c.length, data->column_c.ptr | |
85 | ); | |
86 | } | |
87 | ||
88 | // cleanup everything, no manual free() needed | |
89 | cxMempoolFree(pool); | |
90 | ||
91 | return 0; | |
92 | } | |
93 | ``` | |
94 | ||
1142
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
95 | ## Undocumented Symbols (TODO) |
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
96 | ### cxMempoolCreate |
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
97 | ### cxMempoolFree |
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
98 | ### cxMempoolRegister |
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
99 | ### cxMempoolRemoveDestructor |
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
100 | ### cxMempoolSetDestructor |