88 Please refer to the API doc for the fields prefixed with `flush_` to learn more. |
88 Please refer to the API doc for the fields prefixed with `flush_` to learn more. |
89 |
89 |
90 ## Memory Pool |
90 ## Memory Pool |
91 |
91 |
92 *Header file:* [mempool.h](api/mempool_8h.html) |
92 *Header file:* [mempool.h](api/mempool_8h.html) |
|
93 |
|
94 A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. |
|
95 It also allows you to register destructor functions for the allocated memory, which are automatically called before |
|
96 the memory is deallocated. |
|
97 Additionally, you may also register _independent_ destructor functions within a pool in case some external library |
|
98 allocated memory for you, which should be destroyed together with this pool. |
|
99 |
|
100 Many UCX features support the use of an allocator. |
|
101 The [strings](#string), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. |
|
102 You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with |
|
103 just a single call to `cxMempoolDestroy()`. |
|
104 |
|
105 The following code illustrates this on the example of reading a CSV file into memory. |
|
106 ```C |
|
107 #include <stdio.h> |
|
108 #include <cx/mempool.h> |
|
109 #include <cx/linked_list.h> |
|
110 #include <cx/string.h> |
|
111 #include <cx/buffer.h> |
|
112 #include <cx/utils.h> |
|
113 |
|
114 typedef struct { |
|
115 cxstring column_a; |
|
116 cxstring column_b; |
|
117 cxstring column_c; |
|
118 } CSVData; |
|
119 |
|
120 int main(void) { |
|
121 CxMempool* pool = cxBasicMempoolCreate(128); |
|
122 |
|
123 FILE *f = fopen("test.csv", "r"); |
|
124 if (!f) { |
|
125 perror("Cannot open file"); |
|
126 return 1; |
|
127 } |
|
128 // close the file automatically at pool destruction |
|
129 cxMempoolRegister(pool, f, (cx_destructor_func) fclose); |
|
130 |
|
131 // create a buffer using the memory pool for destruction |
|
132 CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); |
|
133 |
|
134 // read the file into the buffer and turn it into a string |
|
135 cx_stream_copy(f, content, (cx_read_func) fread, (cx_write_func) cxBufferWrite); |
|
136 cxstring contentstr = cx_strn(content->space, content->size); |
|
137 |
|
138 // split the string into lines - use the mempool for allocating the target array |
|
139 cxstring* lines; |
|
140 size_t lc = cx_strsplit_a(pool->allocator, contentstr, |
|
141 CX_STR("\n"), SIZE_MAX, &lines); |
|
142 |
|
143 // skip the header and parse the remaining data into a linked list |
|
144 // the nodes of the linked list shall also be allocated by the mempool |
|
145 CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); |
|
146 for (size_t i = 1 ; i < lc ; i++) { |
|
147 if (lines[i].length == 0) continue; |
|
148 cxstring fields[3]; |
|
149 size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); |
|
150 if (fc != 3) { |
|
151 fprintf(stderr, "Syntax error in line %zu.\n", i); |
|
152 cxMempoolDestroy(pool); |
|
153 return 1; |
|
154 } |
|
155 CSVData* data = cxMalloc(pool->allocator, sizeof(CSVData)); |
|
156 data->column_a = fields[0]; |
|
157 data->column_b = fields[1]; |
|
158 data->column_c = fields[2]; |
|
159 cxListAdd(datalist, data); |
|
160 } |
|
161 |
|
162 // iterate through the list and output the data |
|
163 CxIterator iter = cxListIterator(datalist); |
|
164 cx_foreach(CSVData*, data, iter) { |
|
165 printf("Column A: %.*s | " |
|
166 "Column B: %.*s | " |
|
167 "Column C: %.*s\n", |
|
168 (int)data->column_a.length, data->column_a.ptr, |
|
169 (int)data->column_b.length, data->column_b.ptr, |
|
170 (int)data->column_c.length, data->column_c.ptr |
|
171 ); |
|
172 } |
|
173 |
|
174 // cleanup everything, no manual free() needed |
|
175 cxMempoolDestroy(pool); |
|
176 |
|
177 return 0; |
|
178 } |
|
179 ``` |
93 |
180 |
94 ## Iterator |
181 ## Iterator |
95 |
182 |
96 *Header file:* [iterator.h](api/iterator_8h.html) |
183 *Header file:* [iterator.h](api/iterator_8h.html) |
97 |
184 |