docs/src/features.md

changeset 729
600d72644919
parent 727
d92a59f5d261
child 730
9fecb2769d32
equal deleted inserted replaced
728:71c4ac35c1ce 729:600d72644919
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

mercurial