145 ## Destructor Functions |
145 ## Destructor Functions |
146 |
146 |
147 The `allocator.h` header also declares two function pointers for destructor functions. |
147 The `allocator.h` header also declares two function pointers for destructor functions. |
148 |
148 |
149 ```C |
149 ```C |
|
150 #include <cx/allocator.h> |
|
151 |
150 typedef void (*cx_destructor_func)(void *memory); |
152 typedef void (*cx_destructor_func)(void *memory); |
151 typedef void (*cx_destructor_func2)(void *data, void *memory); |
153 typedef void (*cx_destructor_func2)(void *data, void *memory); |
152 ``` |
154 ``` |
153 |
155 |
154 The first one is called _simple_ destructor (e.g. in the context of [collections](collection.h.md)), |
156 The first one is called _simple_ destructor (e.g. in the context of [collections](collection.h.md)), |
169 > For example, when you are using a [list](list.h.md) that stores elements directly, a destructor function |
171 > For example, when you are using a [list](list.h.md) that stores elements directly, a destructor function |
170 > assigned to that collection may only destroy the element's contents but must not deallocate the element's memory. |
172 > assigned to that collection may only destroy the element's contents but must not deallocate the element's memory. |
171 > On the other hand, when the list is storing just pointers to the elements, you _may_ want the destructor |
173 > On the other hand, when the list is storing just pointers to the elements, you _may_ want the destructor |
172 > function to also deallocate the element's memory when the element is removed from that list. |
174 > function to also deallocate the element's memory when the element is removed from that list. |
173 |
175 |
|
176 ## Clone Function |
|
177 |
|
178 ```C |
|
179 #include <cx/allocator.h> |
|
180 |
|
181 typedef void*(cx_clone_func)( |
|
182 void *target, const void *source, |
|
183 const CxAllocator *allocator, |
|
184 void *data); |
|
185 ``` |
|
186 |
|
187 A clone function is a callback invoked when a deep copy of an object is supposed to be made. |
|
188 If `target` is not `NULL`, memory for the first level was already allocated, and only the deeper levels need to |
|
189 be allocated by the clone function. |
|
190 If `target` is `NULL`, the clone function must allocate all memory. |
|
191 The `source` pointer is never `NULL` and points to the source object. |
|
192 The optional `data` pointer can be used to pass additional state. |
|
193 |
|
194 A very basic clone function that performs a deep copy of a struct with two strings is shown below. |
|
195 |
|
196 ```C |
|
197 #include <cx/string.h> |
|
198 #include <cx/allocator.h> |
|
199 |
|
200 struct kv_pair { |
|
201 cxmutstr key; |
|
202 cxmutstr value; |
|
203 }; |
|
204 |
|
205 void *clone_kv_pair( |
|
206 void *target, const void *source, |
|
207 const CxAllocator *allocator, |
|
208 [[maybe_unused]] void *data) { |
|
209 const struct kv_pair *src = source; |
|
210 struct kv_pair *dst; |
|
211 if (target == NULL) { |
|
212 dst = cxMalloc(allocator, sizeof(struct kv_pair)); |
|
213 } else { |
|
214 dst = target; |
|
215 } |
|
216 dst->key = cx_strdup_a(allocator, src->key); |
|
217 dst->value = cx_strdup_a(allocator, src->value); |
|
218 return dst; |
|
219 } |
|
220 ``` |
|
221 |
|
222 Clone functions are, for example, used by the functions to clone [lists](list.h.md#clone) or maps. |
|
223 |
174 <seealso> |
224 <seealso> |
175 <category ref="apidoc"> |
225 <category ref="apidoc"> |
176 <a href="https://ucx.sourceforge.io/api/allocator_8h.html">allocator.h</a> |
226 <a href="https://ucx.sourceforge.io/api/allocator_8h.html">allocator.h</a> |
177 </category> |
227 </category> |
178 </seealso> |
228 </seealso> |