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