代码之家  ›  专栏  ›  技术社区  ›  Kirill V. Lyadvinsky

为什么我需要std::get\u temporary\u buffer?

  •  82
  • Kirill V. Lyadvinsky  · 技术社区  · 15 年前

    std::get_temporary_buffer ? 标准规定如下:

    获取一个指向足以存储n个相邻T对象的存储的指针。

    ::operator new ,它也不构造对象。下面的陈述是等价的,对吗?

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

    这个函数只存在于syntax sugar吗?为什么会有 temporary 以它的名义?


    报告中提出了一个用例 Dr. Dobb's Journal, July 01, 1996

    如果无法分配缓冲区,或者缓冲区小于请求的缓冲区,则算法仍能正常工作,只会减慢速度。

    6 回复  |  直到 12 年前
        1
  •  47
  •   Georg Fritzsche    10 年前

    “C++程序设计语言” ( ,东南):

    其思想是,一个系统可以保持一些固定大小的缓冲区,以便快速分配,以便请求的空间 n 对象可能会产生超过 n . 然而,它也可能产生较少的收益,因此 get_temporary_buffer() 就是乐观地要求很多,然后利用现有的资源。
    […]因为 获取临时缓冲区() 是低级别的,并且可能为管理临时缓冲区而优化,因此不应将其用作 新的 分配器::allocate() 为了获得长期储存。

    算法通常需要临时空间来执行。

    ... 但似乎没有给出 暂时的 长期 任何地方。

    anecdote 在里面 "From Mathematics to Generic Programming" 提到Stepanov在原始STL设计中提供了一个伪占位符实现,但是:

    令他惊讶的是,几年后他发现所有提供STL实现的主要供应商仍然在使用这种糟糕的实现[…]

        2
  •  19
  •   Jeremy    11 年前

    微软的标准图书馆人员说( here ):

    它有一个非常特殊的用途。注意它不会抛出 不像新的。

    STL在诸如stable\u partition()之类的算法中内部使用它。 当出现像N3126 25.3.13这样的神奇词汇时,就会出现这种情况 [alg.partitions]/11:稳定的\u partition()最多有“复杂性”(last -第一个)*日志(最后一个-第一个)交换,但只有线性数的交换,如果有足够的额外内存 足够的额外内存”出现时,STL使用get\u temporary\u buffer()来 试图获得工作空间。如果可以,那么它就可以实现 算法更有效。如果不能,因为系统正在运行 该算法可以退回到一个较慢的技术。

    99.9%的STL用户永远不需要知道get\u temporary\u buffer()。

        3
  •  9
  •   Stack Overflow is garbage    15 年前

    标准说它为 高达 n 元素。

    不过,似乎很难想象一个好的用例。如果你在一个内存非常有限的平台上工作,这可能是一个获得“尽可能多的内存”的方便方法。

    但是在这样一个受限的平台上,我可以想象您会尽可能地绕过内存分配器,使用一个内存池或您完全控制的东西。

        4
  •  5
  •   Raedwald    8 年前

    我应该用什么 std::get_temporary_buffer?

    The function 在C++ 17中被禁止,所以正确的答案是“没有目的,不要使用它”。

        5
  •  2
  •   OwnWaterloo    15 年前
    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 ) );
    

    实际尺寸 必须大于或等于 要求 .

        6
  •  2
  •   Daniel Munoz    14 年前

    也许(只是猜测)这与内存碎片有关。如果您一直在大量地分配和释放临时内存,但是每次这样做时,您都会在分配临时内存之后但在释放临时内存之前分配一些长期的预期内存,那么您可能最终会得到一个碎片堆(我猜)。

    因此,get\u temporary\u缓冲区可能比您需要的内存块更大,只分配一次(可能有许多块准备好接受多个请求),每次需要内存时,您只会得到其中一块。所以记忆不会变得支离破碎。

    推荐文章