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
>

Reply via email to