std::alloca...ate_at_least(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

okay so this is std::allocator::allocate_at_least, from the C++ Standard Libary manual β€” the page label up top is std::alloca...ate_at_least(3), and yes bestie, we are doing the (since C++23) thing πŸ’…


🌸 Synopsis 🌸

here's the signature tea β˜•:

[[nodiscard]] constexpr std::allocation_result<T*, std::size_t>
allocate_at_least( std::size_t n );

(since C++23) β€” that's the version tag, iykyk ✨

Allocates count * sizeof(T) bytes of uninitialized storage, where count is an unspecified integer value not less than n, by calling ::operator new (an additional std::align_val_t argument might be provided), but it is unspecified when and how this function is called.

Then, this function creates an array of type T[count] in the storage and starts its lifetime, but does not start lifetime of any of its elements.

In order to use this function in a constant expression, the allocated storage must be deallocated within the evaluation of the same expression.

Use of this function is ill-formed if T is an incomplete type.


πŸŽ€ Parameters πŸŽ€

  • n β€” the lower bound of number of objects to allocate storage for. literally the minimum, bestie 🫢

πŸ¦‹ Return value πŸ¦‹

It hands back std::allocation_result<T*>{p, count}, where p points to the first element of an array of count objects of type T whose elements have not been constructed yet. no construction has happened, it's giving freshly reserved space πŸ’…


🌈 Exceptions 🌈

Throws std::bad_array_new_length if std::numeric_limits<std::size_t>::max() / sizeof(T) < n, or std::bad_alloc if allocation fails. math said no and memory said no, respectively 😭


✨ Notes ✨

allocate_at_least is mainly provided for contiguous containers, e.g. std::vector and std::basic_string, in order to reduce reallocation by making their capacity match the actually allocated size when possible. capacity matching = less reallocation drama πŸ”₯

The "unspecified when and how" wording makes it possible to combine or optimize away heap allocations made by the standard library containers, even though such optimizations are disallowed for direct calls to ::operator new. For example, this is implemented by libc++ ([1] and [2]).

After calling allocate_at_least and before construction of elements, pointer arithmetic of T* is well-defined within the allocated array, but the behavior is undefined if elements are accessed. so pointer math is okay, touching the elements is not β€” do not test fate πŸ’€

feature-test macro moment πŸ‘‘:

  • __cpp_lib_allocate_at_least β€” value 202302L, std (C++23), feature: allocate_at_least etc.

🧚 Example 🧚

// Run this code

#include <memory>
#include <print>

int main()
{
    const std::size_t count{69};
    std::allocator<int> alloc;
    std::allocation_result res{alloc.allocate_at_least(count)};
    std::print("count: {}\n"
               "res.ptr: {}\n"
               "res.count: {}\n", count, res.ptr, res.count);

    /* construct, use, then destroy elements */

    alloc.deallocate(res.ptr, res.count);
}

πŸ’» Possible output πŸ’»

count: 69
res.ptr: 0x555a486a0960
res.count: 96

πŸ’œ See also πŸ’œ

  • allocation_result β€” records the address and the actual size of storage allocated by (C++23) allocate_at_least (class template) πŸŽ€
  • allocate_at_least [static] (C++23) β€” allocates storage at least as large as the requested size via an allocate_at_least allocator (public static member function of std::allocator_traits<Alloc>) 🌟

sign-off bestie: source http://cppreference.com, version/date 2024.06.10, page std::alloca...ate_at_least(3) β€” mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from