From 1aed75abda80fc262fe35b07886b92b15558090a Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 6 May 2026 10:48:10 +0200 Subject: [PATCH 1/3] preserve errno in h_free_aligned_sized large path Mirrors the save/restore added to h_free_sized in commit ff431a4. The new h_free_aligned_sized entry point landed in 9a44297 just before that fix and was missed. deallocate_large -> regions_quarantine_deallocate_pages calls mmap/munmap/madvise/prctl which clobber errno, observable through C++17 sized-aligned operator delete. --- h_malloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/h_malloc.c b/h_malloc.c index 88d50c9..4bf1379 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -1796,7 +1796,9 @@ EXPORT void h_free_aligned_sized(void *p, size_t alignment, size_t expected_size return; } + int saved_errno = errno; deallocate_large(p, &expected_size); + errno = saved_errno; thread_seal_metadata(); } From 6ca4d8d7095e7b4e9ceb536ffc513a8800bbdd70 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 6 May 2026 10:48:14 +0200 Subject: [PATCH 2/3] fix typo in get_large_size_class size class comment --- h_malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h_malloc.c b/h_malloc.c index 4bf1379..070f5d1 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -1364,7 +1364,7 @@ static size_t get_large_size_class(size_t size) { // Continue small size class growth pattern of power of 2 spacing classes: // // 4 KiB [20 KiB, 24 KiB, 28 KiB, 32 KiB] - // 8 KiB [40 KiB, 48 KiB, 54 KiB, 64 KiB] + // 8 KiB [40 KiB, 48 KiB, 56 KiB, 64 KiB] // 16 KiB [80 KiB, 96 KiB, 112 KiB, 128 KiB] // 32 KiB [160 KiB, 192 KiB, 224 KiB, 256 KiB] // 512 KiB [2560 KiB, 3 MiB, 3584 KiB, 4 MiB] From 536384e6ce2be3ef9b78348aed3edd98a28d6d46 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 6 May 2026 10:48:18 +0200 Subject: [PATCH 3/3] README: document free_aligned_sized API extension --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 089dd1a..7e63a2a 100644 --- a/README.md +++ b/README.md @@ -775,6 +775,11 @@ sized deallocation sanity checks for C. A performance-oriented allocator could use the same API as an optimization to avoid a potential cache miss from reading the size from metadata. +The `void free_aligned_sized(void *ptr, size_t alignment, size_t expected_size)` +function is the aligned counterpart to `free_sized`, checking both the size and +alignment passed at allocation time. It is used to implement C++17 sized +`operator delete` for over-aligned types. + The `size_t malloc_object_size(void *ptr)` function returns an *upper bound* on the accessible size of the relevant object (if any) by querying the malloc implementation. It's similar to the `__builtin_object_size` intrinsic used by