Sat, 08 Feb 2025 20:38:05 +0100
adds documentation for destructor functions and collections
also invented some new macros for the collection.h
relates to #451
1143
0559812df10c
assign proper names to the documentation topics
Mike Becker <universe@uap-core.de>
parents:
1142
diff
changeset
|
1 | # Allocator |
1141 | 2 | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
3 | The allocator interface provides a mechanism to implement own custom allocators |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
4 | that can also be used in many other function in UCX. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
5 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
6 | A default allocator implementation using the stdlib functions is |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
7 | available via the global symbol `cxDefaultAllocator` |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
8 | and UCX also provides a [memory pool](mempool.h.md) implementation. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
9 | You are free to add additional own custom implementations. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
10 | A general sketch that illustrates how to do this can be found [below](#custom-allocator). |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
11 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
12 | ## Overview |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
13 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
14 | ```C |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
15 | void *cxMalloc(const CxAllocator *allocator, size_t n); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
16 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
17 | void *cxCalloc(const CxAllocator *allocator, |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
18 | size_t nmemb, size_t size); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
19 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
20 | void *cxRealloc(const CxAllocator *allocator, void *mem, size_t n); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
21 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
22 | void *cxReallocArray(const CxAllocator *allocator, void *mem, |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
23 | size_t nmemb, size_t size); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
24 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
25 | int cxReallocate(const CxAllocator *allocator, void **mem, size_t n); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
26 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
27 | int cxReallocateArray(const CxAllocator *allocator, void **mem, |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
28 | size_t nmemb, size_t size); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
29 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
30 | void cxFree(const CxAllocator *allocator, void *mem); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
31 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
32 | int cx_reallocate(void **mem, size_t size); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
33 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
34 | int cx_reallocatearray(void **mem, size_t nmemb, size_t size); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
35 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
36 | // predefined allocator that uses stdlib functions |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
37 | CxAllocator *cxDefaultAllocator; |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
38 | ``` |
1146
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
39 | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
40 | > All UCX functions that are not _explicitly_ designed for taking an allocator argument |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
41 | > (recognizable by a `_a` suffix in the function's name) do support a `NULL` argument |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
42 | > in which case the `cxDefaultAllocator` will be used. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
43 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
44 | ## Description |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
45 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
46 | The functions `cxMalloc()`, `cxCalloc()`, `cxRealloc()`, `cxReallocArray()`, and `cxFree()` |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
47 | invoke the memory management functions specified in the `allocator` and should behave like |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
48 | their respective stdlibc pendants. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
49 | Implementations of the allocator interface are strongly encouraged to guarantee this behavior, |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
50 | most prominently that invocations of `cxFree()` with a `NULL`-pointer for `mem` are ignored |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
51 | instead of causing segfault error. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
52 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
53 | Additionally, UCX provides the functions `cxReallocate()` and `cxReallocateArray()`, as well as |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
54 | their independent pendants `cx_reallocate()` and `cx_reallocatearray()`. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
55 | All those functions solve the problem that a possible reallocation might fail, |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
56 | leading to a quite common programming mistake: |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
57 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
58 | ```C |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
59 | // common mistake - mem will be lost hen realloc() returns NULL |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
60 | mem = realloc(mem, capacity + 32); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
61 | if (mem == NULL) // ... do error handling |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
62 | ``` |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
63 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
64 | The above code can be replaced with `cx_reallocate()` which keeps the pointer intact and returns an error code instead. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
65 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
66 | ```C |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
67 | // when cx_reallocate() fails, mem will still point to the old memory |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
68 | if (cx_reallocate(&mem, capacity + 32)) // ... do error handling |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
69 | ``` |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
70 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
71 | > Please pay special attention to always use `cxFree()` and the `cxRealloc()`-family of functions |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
72 | > with the **same** allocator that was used to allocate the memory. |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
73 | {style="warning"} |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
74 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
75 | ## Custom Allocator |
1141 | 76 | |
77 | If you want to define your own allocator, you need to initialize the `CxAllocator` structure | |
78 | with a pointer to an allocator class (containing function pointers for the memory management | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
79 | functions) and an optional pointer to custom data. An example is shown below: |
1141 | 80 | |
81 | ```c | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
82 | |
1141 | 83 | struct my_allocator_state { |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
84 | // ... some internal state ... |
1141 | 85 | }; |
86 | ||
87 | static cx_allocator_class my_allocator_class = { | |
88 | my_malloc_impl, | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
89 | my_realloc_impl, // all these functions are somewhere defined |
1141 | 90 | my_calloc_impl, |
91 | my_free_impl | |
92 | }; | |
93 | ||
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
94 | CxAllocator create_my_allocator(void) { |
1141 | 95 | CxAllocator alloc; |
96 | alloc.cl = &my_allocator_class; | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
97 | struct my_allocator_state *state = malloc(sizeof(*state)); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
98 | // ... initialize state ... |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
99 | alloc.data = state; |
1141 | 100 | return alloc; |
101 | } | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
102 | |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
103 | void destroy_my_allocator(CxAllocator *al) { |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
104 | struct my_allocator_state *state = al->state; |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
105 | // ... destroy state -- |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
106 | free(state); |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
107 | } |
1141 | 108 | ``` |
109 | ||
1171
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
110 | When you are implementing |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
111 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
112 | ## Destructor Functions |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
113 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
114 | The `allocator.h` header also declares two function pointers for destructor functions. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
115 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
116 | ```C |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
117 | typedef void (*cx_destructor_func)(void *memory); |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
118 | typedef void (*cx_destructor_func2)(void *data, void *memory); |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
119 | ``` |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
120 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
121 | The first one is called _simple_ destructor (e.g. in the context of [collections](collection.h.md)), |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
122 | and the second one is called _advanced_ destructor. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
123 | The only difference is that you can pass additional custom `data` to an advanced destructor function. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
124 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
125 | Destructor functions play a vital role in deep de-allocations. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
126 | Another scenarios, besides destroying elements in a collection, are the de-allocation of objects |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
127 | stored in a [memory pool](mempool.h.md) or de-allocations of deeply nested [JSON](json.h.md) objects. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
128 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
129 | > Destructor functions are not to be confused with `free()`-like functions. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
130 | > The fundamental differences are that |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
131 | > * it is not safe to pass `NULL` to a destructor function |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
132 | > * a destructor may only de-allocate the contents inside an object but not the object itself, depending on context |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
133 | > |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
134 | {style="note"} |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
135 | |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
136 | > For example, when you are using a [list](list.h.md) that stores elements directly, a destructor function |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
137 | > assigned to that collection may only destroy the element's contents but must not deallocate the element's memory. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
138 | > On the other hand, when the list is storing just pointers to the elements, you _may_ want the destructor |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
139 | > function to also de-allocate the element's memory when the element is removed from that list. |
155bc3b0dcb3
adds documentation for destructor functions and collections
Mike Becker <universe@uap-core.de>
parents:
1169
diff
changeset
|
140 | |
1169
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
141 | <seealso> |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
142 | <category ref="apidoc"> |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
143 | <a href="https://ucx.sourceforge.io/api/allocator_8h.html">allocator.h</a> |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
144 | </category> |
6a33a5648027
add documentation for allocator.h
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
145 | </seealso> |