出于什么目的我应该使用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
?
在Dr. Dobb's Journal, July 01, 1996中建议使用一个用例来实现算法:
如果没有缓冲区可以分配,或者它小于请求的缓冲区,算法仍能正常工作,它只会减慢速度。
答案 0 :(得分:42)
Stroustrup在“C ++编程语言”(§19.4.4,SE)中说:
这个想法是系统可以保留一些固定大小的缓冲区,以便快速分配,这样 n 对象的请求空间可能会产生超过 n 的空间。然而,它也可能产生更少的收益,因此使用
get_temporary_buffer()
的一种方法是乐观地要求很多,然后使用可能发生的事情。
[...]因为get_temporary_buffer()
是低级的并且可能针对管理临时缓冲区进行了优化,所以不应将其用作 new 或 allocator :: allocate的替代方法()以获得更长期的存储空间。
他还开始介绍这两个函数:
算法通常需要临时空间来执行。
...但似乎没有在任何地方提供临时或长期的定义。
anecdote中的"From Mathematics to Generic Programming"提到Stepanov在原始STL设计中提供了虚假的占位符实现,但是:
令他惊讶的是,多年后他发现提供STL实施的所有主要供应商仍在使用这种可怕的实现[...]
答案 1 :(得分:17)
微软的标准图书馆人员说以下内容(here):
- 您是否可以解释何时使用&#39; get_temporary_buffer&#39;
它有一个非常专业的目的。请注意,它不会抛出 异常,如new(nothrow),但它也没有构造对象, 不像新的(nothrow)。
STL在诸如stable_partition()之类的算法中内部使用它。 当有像N3126 25.3.13这样的神奇单词时会发生这种情况 [alg.partitions] / 11:stable_partition()具有复杂性&#34;最多(最后 - 首先)* log(last - first)交换,但是如果有足够的额外内存,则只有交换的线性数量。&#34;当有魔力的话语时,如果有的话 足够的额外记忆&#34;出现,STL使用get_temporary_buffer()来 试图获得工作空间。如果可以,那么它可以实现 算法更有效率。如果它不能,因为系统正在运行 危险地接近内存不足(或涉及的范围很大), 算法可以回归到较慢的技术。
99.9%的STL用户永远不需要了解get_temporary_buffer()。
答案 2 :(得分:9)
标准表示它为最多 n
元素分配存储空间。
换句话说,您的示例可能会返回一个足以容纳5个对象的缓冲区。
看起来很难想象一个好的用例。也许如果你正在一个内存受限的平台上工作,这是获得“尽可能多的内存”的便捷方式。
但是在这样一个受限制的平台上,我想你会尽可能地绕过内存分配器,并使用内存池或你可以完全控制的东西。
答案 3 :(得分:2)
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 ) );
回复可能少于请求。
size_t require = 12;
int* base = static_cast<int*>( ::operator new( require*sizeof(int) ) );
assert( is_valid( base, base + require ) );
base 的实际大小必须大于或等于 require 。
答案 4 :(得分:2)
也许(只是猜测)它与内存碎片有关。如果你大量继续分配和释放临时内存,但是每次执行它都会在分配临时值之后分配一些长期预期的内存,但是在释放它之前,你可能会得到一个碎片堆(我猜)。
所以get_temporary_buffer可能是一个比你需要更大的内存块,它被分配一次(也许有很多块可以接受多个请求),每次你需要内存时你就得到了其中一个块。所以内存不会碎片化。
答案 5 :(得分:2)
我应该使用
std::get_temporary_buffer?
The function在C ++ 17中已被弃用,所以正确的答案现在是“无目的,不要使用它”。