8 This can be useful, for example, when some library allocates memory that you wish to destroy when the memory pool gets destroyed. |
8 This can be useful, for example, when some library allocates memory that you wish to destroy when the memory pool gets destroyed. |
9 |
9 |
10 A memory pool can be used with all UCX features that support the use of an [allocator](allocator.h.md). |
10 A memory pool can be used with all UCX features that support the use of an [allocator](allocator.h.md). |
11 For example, the UCX [string](string.h.md) functions provide several variants suffixed with `_a` for that purpose. |
11 For example, the UCX [string](string.h.md) functions provide several variants suffixed with `_a` for that purpose. |
12 |
12 |
13 ## Overview |
13 ## Basic Memory Management |
14 |
14 |
15 ```C |
15 ```C |
16 #include <cx/mempool.h> |
16 #include <cx/mempool.h> |
17 |
17 |
18 CxMempool *cxMempoolCreate(size_t capacity, cx_destructor_func fnc); |
18 CxMempool *cxMempoolCreate(size_t capacity, cx_destructor_func fnc); |
27 |
27 |
28 int cxMempoolRegister(CxMempool *pool, void *memory, |
28 int cxMempoolRegister(CxMempool *pool, void *memory, |
29 cx_destructor_func fnc); |
29 cx_destructor_func fnc); |
30 ``` |
30 ``` |
31 |
31 |
32 ## Description |
|
33 |
|
34 A memory pool is created with the `cxMempoolCreate()` function with a default `capacity` |
32 A memory pool is created with the `cxMempoolCreate()` function with a default `capacity` |
35 and an optional default destructor function `fnc`. |
33 and an optional default destructor function `fnc`. |
36 If specified, the default destructor function is registered for all freshly allocated memory within the pool, |
34 If specified, the default destructor function is registered for all freshly allocated memory within the pool, |
37 as if `cxMempoolSetDestructor()` was called immediately after allocation. |
35 as if `cxMempoolSetDestructor()` was called immediately after allocation. |
38 When you set `fnc` is to `NULL` during pool creation, or use `cxMempoolCreateSimple`, no default destructor is registered. |
36 When you set `fnc` is to `NULL` during pool creation, or use `cxMempoolCreateSimple`, no default destructor is registered. |
46 The `cxMempoolRegister()` function allocates a new wrapper object for `memory` with `pool`'s allocator that |
44 The `cxMempoolRegister()` function allocates a new wrapper object for `memory` with `pool`'s allocator that |
47 will call the specified destructor function when destroyed. |
45 will call the specified destructor function when destroyed. |
48 Usually this function returns zero except for platforms where memory allocations are likely to fail, |
46 Usually this function returns zero except for platforms where memory allocations are likely to fail, |
49 in which case a non-zero value is returned. |
47 in which case a non-zero value is returned. |
50 |
48 |
51 ## Order of Destruction |
49 ### Order of Destruction |
52 |
50 |
53 When you call `cxMempoolFree()` the following actions are performed: |
51 When you call `cxMempoolFree()` the following actions are performed: |
54 |
52 |
55 1. In any order, for each object in the pool |
53 1. In any order, for each object in the pool |
56 1. the destructor function assigned to that object is called |
54 1. the destructor function assigned to that object is called |
57 2. the object's memory is deallocated |
55 2. the object's memory is deallocated |
58 2. The pool memory is deallocated |
56 2. The pool memory is deallocated |
59 3. The pool structure is deallocated |
57 3. The pool structure is deallocated |
|
58 |
|
59 ## Transfer Memory |
|
60 |
|
61 ```C |
|
62 #include <cx/mempool.h> |
|
63 |
|
64 int cxMempoolTransfer(CxMempool *source, CxMempool *dest); |
|
65 ``` |
|
66 |
|
67 Memory managed by a pool can be transferred to another pool. |
|
68 |
|
69 The function `cxMempoolTransfer()` transfers all memory managed and/or registered with the `source` pool to the `dest` pool. |
|
70 It also registers its allocator with the `dest` pool and creates a new allocator for the `source` pool. |
|
71 That means, that all references to the allocator of the `source` pool remain valid and continue to work with the `dest` pool. |
|
72 The transferred allocator will be destroyed when the `dest` pool gets destroyed. |
|
73 |
|
74 The function returns zero when the transfer was successful and non-zero if a necessary memory allocation was not possible, |
|
75 or the `source` and `dest` pointers point to the same pool. |
|
76 In case of an error, no memory is transferred and both pools are in a valid state. |
|
77 |
|
78 > Although the allocator from the `source` pool remains valid for the already allocated objects, |
|
79 > it is **not** valid to use that allocator to allocate new objects in the `dest` pool. |
|
80 > It may only be used to free or reallocate the memory of the existing objects. |
|
81 > |
|
82 > The reason is, that the allocator will be destroyed after destroying all objects from the `source` pool and |
|
83 > _before_ destroying objects in the `dest` pool which were allocated after the transfer. |
|
84 >{style="warning"} |
|
85 |
60 |
86 |
61 ## Example |
87 ## Example |
62 |
88 |
63 The following code illustrates how the contents of a CSV file are read into pooled memory. |
89 The following code illustrates how the contents of a CSV file are read into pooled memory. |
64 ```C |
90 ```C |