[PATCH] libstdc++: allocate_at_least ask only what it reports (P0401)

Nathan Myers ncm@cantrip.org
Tue May 26 16:19:46 GMT 2026


On 5/26/26 12:17 PM, Jonathan Wakely wrote:
> On Tue, 26 May 2026 at 16:13, Nathan Myers <ncm@cantrip.org> 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
>>
> 



More information about the Libstdc++ mailing list