Mon, 14 May 2018 12:54:37 +0200
comprehensive code example for the memory pool
docs/src/modules.md | file | annotate | diff | comparison | revisions |
1.1 --- a/docs/src/modules.md Sun May 13 17:34:06 2018 +0200 1.2 +++ b/docs/src/modules.md Mon May 14 12:54:37 2018 +0200 1.3 @@ -352,9 +352,110 @@ 1.4 This pool allows you to register destructor functions for the allocated memory, 1.5 which are automatically called on the destruction of the pool. 1.6 But you may also register *independent* destructor functions within a pool in 1.7 -case, some external library allocated memory for you, which you wish to be 1.8 +case some external library allocated memory for you, which should be 1.9 destroyed together with this pool. 1.10 1.11 +Many UCX modules support the use of an allocator. 1.12 +The [String Module](#string), for instance, provides the `sstrdup_a()` function, 1.13 +which uses the specified allocator to allocate the memory for the duplicated 1.14 +string. 1.15 +This way, you can use a `UcxMempool` to keep track of the memory occupied by 1.16 +duplicated strings and cleanup everything with just a single call to 1.17 +`ucx_mempool_destroy()`. 1.18 + 1.19 +### Read CSV data into a structure 1.20 + 1.21 +The following code example shows some of the basic memory pool functions and 1.22 +how they can be used with other UCX modules. 1.23 +```C 1.24 +#include <stdio.h> 1.25 +#include <ucx/mempool.h> 1.26 +#include <ucx/list.h> 1.27 +#include <ucx/string.h> 1.28 +#include <ucx/buffer.h> 1.29 +#include <ucx/utils.h> 1.30 + 1.31 +typedef struct { 1.32 + sstr_t column_a; 1.33 + sstr_t column_b; 1.34 + sstr_t column_c; 1.35 +} CSVData; 1.36 + 1.37 +int main(int argc, char** argv) { 1.38 + 1.39 + UcxMempool* pool = ucx_mempool_new(128); 1.40 + 1.41 + FILE *f = fopen("test.csv", "r"); 1.42 + if (!f) { 1.43 + perror("Cannot open file"); 1.44 + return 1; 1.45 + } 1.46 + /* close the file automatically at pool destruction*/ 1.47 + ucx_mempool_reg_destr(pool, f, (ucx_destructor) fclose); 1.48 + 1.49 + /* create a buffer and register it at the memory pool for destruction */ 1.50 + UcxBuffer* content = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND); 1.51 + ucx_mempool_reg_destr(pool, content, (ucx_destructor) ucx_buffer_free); 1.52 + 1.53 + /* read the file and split it by lines first */ 1.54 + ucx_stream_copy(f, content, fread, ucx_buffer_write); 1.55 + sstr_t contentstr = ucx_buffer_to_sstr(content); 1.56 + ssize_t lc = 0; 1.57 + sstr_t* lines = sstrsplit_a(pool->allocator, contentstr, S("\n"), &lc); 1.58 + 1.59 + /* skip the header and parse the remaining data */ 1.60 + UcxList* datalist = NULL; 1.61 + for (size_t i = 1 ; i < lc ; i++) { 1.62 + if (lines[i].length == 0) continue; 1.63 + ssize_t fc = 3; 1.64 + sstr_t* fields = sstrsplit_a(pool->allocator, lines[i], S(";"), &fc); 1.65 + if (fc != 3) { 1.66 + fprintf(stderr, "Syntax error in line %zu.\n", i); 1.67 + ucx_mempool_destroy(pool); 1.68 + return 1; 1.69 + } 1.70 + CSVData* data = ucx_mempool_malloc(pool, sizeof(CSVData)); 1.71 + data->column_a = fields[0]; 1.72 + data->column_b = fields[1]; 1.73 + data->column_c = fields[2]; 1.74 + datalist = ucx_list_append_a(pool->allocator, datalist, data); 1.75 + } 1.76 + 1.77 + /* control output */ 1.78 + UCX_FOREACH(elem, datalist) { 1.79 + CSVData* data = elem->data; 1.80 + printf("Column A: %" PRIsstr " | " 1.81 + "Column B: %" PRIsstr " | " 1.82 + "Column C: %" PRIsstr "\n", 1.83 + SFMT(data->column_a), SFMT(data->column_b), SFMT(data->column_c) 1.84 + ); 1.85 + } 1.86 + 1.87 + /* cleanup everything, no manual free() needed */ 1.88 + ucx_mempool_destroy(pool); 1.89 + 1.90 + return 0; 1.91 +} 1.92 +``` 1.93 + 1.94 +### Overriding the default destructor 1.95 + 1.96 +Sometimes you need to allocate memory with `ucx_mempool_malloc()`, but the 1.97 +memory is not supposed to be freed with a simple call to `free()`. 1.98 +In this case, you can overwrite the default destructor as follows: 1.99 +```C 1.100 + MyObject* obj = ucx_mempool_malloc(pool, sizeof(MyObject)); 1.101 + 1.102 + /* some special initialization with own resource management */ 1.103 + my_object_init(obj); 1.104 + 1.105 + /* register destructor function */ 1.106 + ucx_mempool_set_destr(obj, (ucx_destructor) my_object_destroy); 1.107 +``` 1.108 +But aware, that your destructor function should not free any memory, that is 1.109 +also managed by the pool. 1.110 +Otherwise you might be risking a double-free. 1.111 + 1.112 ## Properties 1.113 1.114 *Header file:* [properties.h](api/properties_8h.html)