comprehensive code example for the memory pool

Mon, 14 May 2018 12:54:37 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 14 May 2018 12:54:37 +0200
changeset 302
8628147734d6
parent 301
0f83916c1639
child 303
362679052788

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)  

mercurial