[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