为什么我需要 std: : get_Clinical_buffer?

为什么我应该使用 std::get_temporary_buffer? 标准说明如下:

获取一个指向存储区的指针,该指针足以存储多达 n 个相邻 T 对象。

我认为缓冲区将在堆栈上分配,但事实并非如此。根据 C + + 标准,这个缓冲区实际上不是临时的。与不构造对象的全局函数 ::operator new相比,这个函数有什么优势。下面的陈述对等吗?

int* x;
x = std::get_temporary_buffer<int>( 10 ).first;
x = static_cast<int*>( ::operator new( 10*sizeof(int) ) );

这个函数只存在于语法糖吗? 为什么它的名字里有 temporary


多布医生日记,1996年7月1日中提出了一个用于实现算法的用例:

如果不能分配缓冲区,或者缓冲区小于请求的缓冲区,算法仍然能正常工作,只是速度变慢了。

10845 次浏览

The standard says it allocates storage for up to n elements. In other words, your example might return a buffer big enough for 5 objects only.

It does seem pretty difficult to imagine a good use case for this though. Perhaps if you're working on a very memory-constrained platform, it's a convenient way to get "as much memory as possible".

But on such a constrained platform, I'd imagine you'd bypass the memory allocator as much as possible, and use a memory pool or something you have full control over.

ptrdiff_t            request = 12
pair<int*,ptrdiff_t> p       = get_temporary_buffer<int>(request);
int*                 base    = p.first;
ptrdiff_t            respond = p.sencond;
assert( is_valid( base, base + respond ) );

respond may be less than request.

size_t require = 12;
int*   base    = static_cast<int*>( ::operator new( require*sizeof(int) ) );
assert( is_valid( base, base + require ) );

the actual size of base must greater or equal to require.

Stroustrup says in "The C++ Programming Language" (§19.4.4, SE):

The idea is that a system may keep a number of fixed-sized buffers ready for fast allocation so that requesting space for n objects may yield space for more than n. It may also yield less, however, so one way of using get_temporary_buffer() is to optimistically ask for a lot and then use what happens to be available.
[...] Because get_temporary_buffer() is low-level and likely to be optimized for managing temporary buffers, it should not be used as an alternative to new or allocator::allocate() for obtaining longer-term storage.

He also starts the introduction to the two functions with:

Algorithms often require temporary space to perform acceptably.

... but doesn't seem to provide a definition of temporary or longer-term anywhere.

An anecdote in "From Mathematics to Generic Programming" mentions that Stepanov provided a bogus placeholder implementation in the original STL design, however:

To his surprise, he discovered years later that all the major vendors that provide STL implementations are still using this terrible implementation [...]

Perhaps (just a guess) it has something to do with memory fragmentation. If you heavily keep allocating and deallocating temporal memory, but each time you do it you allocate some long-term intended memory after allocating the temp but before deallocating it, you may end up with a fragmented heap (I guess).

So the get_temporary_buffer could be intended to be a bigger-than-you-would-need chunk of memory that is allocated once (perhaps there are many chunks ready for accepting multiple requests), and each time you need memory you just get one of the chunks. So the memory doesn't get fragmented.

Microsoft's standard library guy says the following (here):

  • Could you perhaps explain when to use 'get_temporary_buffer'

It has a very specialized purpose. Note that it doesn't throw exceptions, like new (nothrow), but it also doesn't construct objects, unlike new (nothrow).

It's used internally by the STL in algorithms like stable_partition(). This happens when there are magic words like N3126 25.3.13 [alg.partitions]/11: stable_partition() has complexity "At most (last - first) * log(last - first) swaps, but only linear number of swaps if there is enough extra memory." When the magic words "if there is enough extra memory" appear, the STL uses get_temporary_buffer() to attempt to acquire working space. If it can, then it can implement the algorithm more efficiently. If it can't, because the system is running dangerously close to out-of-memory (or the ranges involved are huge), the algorithm can fall back to a slower technique.

99.9% of STL users will never need to know about get_temporary_buffer().

For what purpose I should use std::get_temporary_buffer?

The function is deprecated in C++17, so the correct answer is now "for no purpose, do not use it".