On 5/26/26 12:17 PM, Jonathan Wakely wrote:
On Tue, 26 May 2026 at 16:13, Nathan Myers <[email protected]> wrote:allocate_at_least rounds up the allocation request size to its default alignment, which may be more than an integral multiple of the object size requested. When the memory is freed, what the container reports it is freeing differs from the amount that was allocated. This patch rounds the request size back down to what will be reported to the caller. libstdc++-v3/ChangeLog: * include/bits/new_allocator.h (allocate_at_least): Reduce allocation to match what is reported.The code change looks good. Can you also construct a test using __gnu_test::tracker_allocator which fails without the fix? Hmm, no, because the tracker_allocator only sees the return value from __new_allocator::allocate_at_least which is correct (it's already been adjusted to ignore the problematic extra bytes). I think we'd need a testcase that replaces operator new / operator delete and verifies that the numbers match. Could you try that?
I will essay it.
--- libstdc++-v3/include/bits/new_allocator.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/bits/new_allocator.h b/libstdc++-v3/include/bits/new_allocator.h index 4524355a4a0..8d67b2d93fa 100644 --- a/libstdc++-v3/include/bits/new_allocator.h +++ b/libstdc++-v3/include/bits/new_allocator.h @@ -189,12 +189,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t __ask = (__need + __mask) & ~__mask; // Avoid rounding up to and asking for 2^63 bytes (PR108377): __ask -= __ask >> (__SIZE_WIDTH__ - 1); - auto* __p = static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__ask)); using _U8 = const unsigned char; static_assert(sizeof(_Tp) <= ~_U8()); - // Use 8-bit division for minimal latency: + // Use 8-bit arithmetic for minimal latency: _U8 __spare = __ask - __need, __size = sizeof(_Tp); - return { __p , __n + __spare / __size }; + __n += __spare / __size; + __ask -= __spare % __size; + auto* __p = static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__ask)); + return { __p, __n }; } } return { allocate(__n), __n }; -- 2.54.0
