# HG changeset patch # User Mike Becker # Date 1761168740 -7200 # Node ID 2ca9e03ceeecd76f6319e3ec8cba4d762fa526f8 # Parent dde4903c0fd74438ef931f84db8c25d942cd5dcb add destruction of uninitialized entries on allocation failure to cxMapClone() - relates to #743 diff -r dde4903c0fd7 -r 2ca9e03ceeec src/map.c --- a/src/map.c Wed Oct 22 23:28:07 2025 +0200 +++ b/src/map.c Wed Oct 22 23:32:20 2025 +0200 @@ -128,6 +128,16 @@ map->cl->deallocate(map); } +static void cx_map_remove_uninitialized_entry(CxMap *map, CxHashKey key) { + cx_destructor_func destr_bak = map->collection.simple_destructor; + cx_destructor_func2 destr2_bak = map->collection.advanced_destructor; + map->collection.simple_destructor = NULL; + map->collection.advanced_destructor = NULL; + cxMapRemove(map, key); + map->collection.simple_destructor = destr_bak; + map->collection.advanced_destructor = destr2_bak; +} + size_t cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { CxMapIterator src_iter = cxMapIterator(src); @@ -141,7 +151,7 @@ } void *dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); if (dst_ptr == NULL) { - // TODO: remove the entry to avoid calling destructors on uninitialized memory + cx_map_remove_uninitialized_entry(dst, *(entry->key)); return i; } *dst_mem = dst_ptr; @@ -155,7 +165,7 @@ return i; } if (clone_func(dst_mem, entry->value, clone_allocator, data) == NULL) { - // TODO: remove the entry to avoid calling destructors on uninitialized memory + cx_map_remove_uninitialized_entry(dst, *(entry->key)); return i; } cxIteratorNext(src_iter);