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?
> ---
> 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
>