docs/src/modules.md

changeset 302
8628147734d6
parent 301
0f83916c1639
child 304
1f9237cfeb26
equal deleted inserted replaced
301:0f83916c1639 302:8628147734d6
350 350
351 Here we have a concrete allocator implementation in the sense of a memory pool. 351 Here we have a concrete allocator implementation in the sense of a memory pool.
352 This pool allows you to register destructor functions for the allocated memory, 352 This pool allows you to register destructor functions for the allocated memory,
353 which are automatically called on the destruction of the pool. 353 which are automatically called on the destruction of the pool.
354 But you may also register *independent* destructor functions within a pool in 354 But you may also register *independent* destructor functions within a pool in
355 case, some external library allocated memory for you, which you wish to be 355 case some external library allocated memory for you, which should be
356 destroyed together with this pool. 356 destroyed together with this pool.
357
358 Many UCX modules support the use of an allocator.
359 The [String Module](#string), for instance, provides the `sstrdup_a()` function,
360 which uses the specified allocator to allocate the memory for the duplicated
361 string.
362 This way, you can use a `UcxMempool` to keep track of the memory occupied by
363 duplicated strings and cleanup everything with just a single call to
364 `ucx_mempool_destroy()`.
365
366 ### Read CSV data into a structure
367
368 The following code example shows some of the basic memory pool functions and
369 how they can be used with other UCX modules.
370 ```C
371 #include <stdio.h>
372 #include <ucx/mempool.h>
373 #include <ucx/list.h>
374 #include <ucx/string.h>
375 #include <ucx/buffer.h>
376 #include <ucx/utils.h>
377
378 typedef struct {
379 sstr_t column_a;
380 sstr_t column_b;
381 sstr_t column_c;
382 } CSVData;
383
384 int main(int argc, char** argv) {
385
386 UcxMempool* pool = ucx_mempool_new(128);
387
388 FILE *f = fopen("test.csv", "r");
389 if (!f) {
390 perror("Cannot open file");
391 return 1;
392 }
393 /* close the file automatically at pool destruction*/
394 ucx_mempool_reg_destr(pool, f, (ucx_destructor) fclose);
395
396 /* create a buffer and register it at the memory pool for destruction */
397 UcxBuffer* content = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND);
398 ucx_mempool_reg_destr(pool, content, (ucx_destructor) ucx_buffer_free);
399
400 /* read the file and split it by lines first */
401 ucx_stream_copy(f, content, fread, ucx_buffer_write);
402 sstr_t contentstr = ucx_buffer_to_sstr(content);
403 ssize_t lc = 0;
404 sstr_t* lines = sstrsplit_a(pool->allocator, contentstr, S("\n"), &lc);
405
406 /* skip the header and parse the remaining data */
407 UcxList* datalist = NULL;
408 for (size_t i = 1 ; i < lc ; i++) {
409 if (lines[i].length == 0) continue;
410 ssize_t fc = 3;
411 sstr_t* fields = sstrsplit_a(pool->allocator, lines[i], S(";"), &fc);
412 if (fc != 3) {
413 fprintf(stderr, "Syntax error in line %zu.\n", i);
414 ucx_mempool_destroy(pool);
415 return 1;
416 }
417 CSVData* data = ucx_mempool_malloc(pool, sizeof(CSVData));
418 data->column_a = fields[0];
419 data->column_b = fields[1];
420 data->column_c = fields[2];
421 datalist = ucx_list_append_a(pool->allocator, datalist, data);
422 }
423
424 /* control output */
425 UCX_FOREACH(elem, datalist) {
426 CSVData* data = elem->data;
427 printf("Column A: %" PRIsstr " | "
428 "Column B: %" PRIsstr " | "
429 "Column C: %" PRIsstr "\n",
430 SFMT(data->column_a), SFMT(data->column_b), SFMT(data->column_c)
431 );
432 }
433
434 /* cleanup everything, no manual free() needed */
435 ucx_mempool_destroy(pool);
436
437 return 0;
438 }
439 ```
440
441 ### Overriding the default destructor
442
443 Sometimes you need to allocate memory with `ucx_mempool_malloc()`, but the
444 memory is not supposed to be freed with a simple call to `free()`.
445 In this case, you can overwrite the default destructor as follows:
446 ```C
447 MyObject* obj = ucx_mempool_malloc(pool, sizeof(MyObject));
448
449 /* some special initialization with own resource management */
450 my_object_init(obj);
451
452 /* register destructor function */
453 ucx_mempool_set_destr(obj, (ucx_destructor) my_object_destroy);
454 ```
455 But aware, that your destructor function should not free any memory, that is
456 also managed by the pool.
457 Otherwise you might be risking a double-free.
357 458
358 ## Properties 459 ## Properties
359 460
360 *Header file:* [properties.h](api/properties_8h.html) 461 *Header file:* [properties.h](api/properties_8h.html)
361 *Required modules:* [Map](#map) 462 *Required modules:* [Map](#map)

mercurial