Closed
Description
https://eel.is/c++draft/vector.capacity#9.sentence-3
constexpr void shrink_to_fit();
Effects: [...] It does not increasecapacity()
, but may reducecapacity()
by causing reallocation.
https://godbolt.org/z/hP63rn661
#include <vector>
#include <memory>
#include <algorithm>
std::size_t min_bytes = 1000;
template<typename T>
struct increasing_allocator {
using value_type = T;
increasing_allocator() = default;
template<typename U>
constexpr increasing_allocator(const increasing_allocator<U>&) noexcept {}
std::allocation_result<T*> allocate_at_least(std::size_t n) {
std::size_t allocation_amount = n * sizeof(T);
if (allocation_amount < min_bytes) allocation_amount = min_bytes;
min_bytes += 1000;
return { static_cast<T*>(::operator new(allocation_amount)), allocation_amount };
}
T* allocate(std::size_t n) {
return allocate_at_least(n).ptr;
}
void deallocate(T* p, std::size_t n) noexcept {
::operator delete(static_cast<void*>(p));
}
};
template<typename T, typename U>
constexpr bool operator==(increasing_allocator<T>, increasing_allocator<U>) { return true; }
int main() {
std::vector<int, increasing_allocator<int>> x;
x.push_back(1);
__builtin_printf("Before shrink cap: %zu\n", x.capacity());
x.shrink_to_fit();
__builtin_printf("After shrink cap: %zu\n", x.capacity());
}
Before shrink cap: 1000
After shrink cap: 2000
The new capacity isn't checked before the elements are moved to the new allocation:
llvm-project/libcxx/include/vector
Lines 1438 to 1440 in a13bc97
This came up when using an arena allocator and the smaller arenas filled up and shrink_to_fit
didn't help