std::get_temporary_buffer(3)
π std::get_temporary_buffer β a C++ Standard Library moment (section 3, bestie)
Okay so picture this: it's the <memory> header, and there's this function template that's giving "I was supposed to be the efficient one" but honestly it's giving "retired icon". Buckle up, because this one has lore. π
β¨ NAME β¨
std::get_temporary_buffer β yes, that's literally the name, we're not doing a whole bit about it, it's just std::get_temporary_buffer. π
πΈ Synopsis πΈ
So it lives in the header <memory>, and it's a template on class T. There are two versions and you literally need to know which standard you're on, iykyk:
The old one (until C++11):
template< class T >
std::pair<T*, std::ptrdiff_t>
get_temporary_buffer( std::ptrdiff_t count );
The new one (since C++11, deprecated in C++17, removed in C++20) β yes, all three of those tags, she had a whole lifecycle:
template< class T >
std::pair<T*, std::ptrdiff_t>
get_temporary_buffer( std::ptrdiff_t count ) noexcept;
Okay so what does she do? If count is negative or zero, she does nothing. Nothing at all. Ghosted. π»
Otherwise, she requests to allocate uninitialized contiguous storage for count adjacent objects of type T. And here's the gag: the request is non-binding. The implementation may instead allocate the storage for any other number of (including zero!) adjacent objects of type T. So you ask nicely and she does whatever she wants, lowkey iconic behavior honestly. π
Also it is implementation-defined whether over-aligned types are supported. (since C++11) β so don't come for her if your over-aligned type doesn't get the memo. π
π¦ Parameters π¦
countβ the desired number of objects. Desired, bestie. Desired. She'll do her best. π
β Return value β
You get back a std::pair. Let me break it down because both members matter:
- the member
firstis a pointer to the beginning of the allocated storage - the member
secondis the number of objects that fit in the storage that was actually allocated
And here's the important part β the reality check: if count <= 0, or the allocated storage is not enough to store a single element of type T, then the member first of the result is a null pointer and the member second is zero. So like... always check, fr fr. π«Ά
π Notes π
Storytime, because this is genuinely tragic lore: this API was originally designed with the intent of providing a more efficient implementation than the general-purpose operator new. Did such an implementation ever get created? No. Not one. So the API was deprecated and removed. She had a vision and the standards committee said "no β€οΈ". Rest in peace, queen. ππ
π Example π
Run this code, I promise it's a cute little demonstration:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
#include <string>
int main()
{
const std::string s[] = {"string", "1", "test", "..."};
const auto p = std::get_temporary_buffer<std::string>(4);
// requires that p.first is passed to return_temporary_buffer
// (beware of early exit points and exceptions), or better use:
std::unique_ptr<std::string, void(*)(std::string*)> on_exit(p.first,
[](std::string* p)
{
std::cout << "returning temporary buffer...\n";
std::return_temporary_buffer(p);
});
std::copy(s, s + p.second,
std::raw_storage_iterator<std::string*, std::string>(p.first));
// has same effect as: std::uninitialized_copy(s, s + p.second, p.first);
// requires that each string in p is individually destroyed
// (beware of early exit points and exceptions)
std::copy(p.first, p.first + p.second,
std::ostream_iterator<std::string>{std::cout, "\n"});
std::for_each(p.first, p.first + p.second, [](std::string& e)
{
e.~basic_string<char>();
}); // same as: std::destroy(p.first, p.first + p.second);
// manually reclaim memory if unique_ptr-like technique is not used:
// std::return_temporary_buffer(p.first);
}
Note those comments, bestie β they're not decoration, they're warnings. If you don't hand p.first to return_temporary_buffer you're leaking, and the "beware of early exit points and exceptions" note applies to both the buffer itself and the individually-destroyed strings. Use the unique_ptr-style technique, it's the main character move here. π
π Output
string
1
test
...
returning temporary buffer...
Ate. No crumbs. β¨
π Defect reports π
Real ones will remember: the following behavior-changing defect reports were applied retroactively to previously published C++ standards. Past you was out here guessing and it was not the vibe.
- LWG 425 β applied to C++98 β as published, the behavior when
count <= 0was unclear; correct behavior: made clear. π - LWG 2072 β applied to C++98 β as published, it was not allowed to allocate insufficient memory; correct behavior: allowed. π¦
(Like I said β she's allowed to give you less than you asked for. It's in the defect reports. It's canon.)
π§ See also π§
return_temporary_bufferβ frees uninitialized storage. (deprecated in C++17) (removed in C++20) β it's a function template, and it's the other half of this whole situation, don't forget her. πallocate_at_leastβ allocates storage at least as large as the requested size via an allocator.[static](C++23), and it's a public static member function ofstd::allocator_traits<Alloc>. This is the spiritual successor bestie, she actually delivers. π₯
Okay so the takeaway: she's deprecated, she's removed in C++20, she's non-binding about how much she gives you, and she may hand back a null pointer. Love her, learn her, then go use allocate_at_least. π
β¨
Sign-off time π«Ά β this little page came from http://cppreference.com, dated 2024.06.10, and it's page std::get_temporary_buffer(3) of the manual. Mwah, go write some RAII. π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms