未使用的STL容器是否分配内存?

sil*_*orb 13 c++ stl allocation stdmap stdvector

鉴于代码:

class Foo {
  std::vector<int> items;
  std::map<int, int> dictionary;
};
Run Code Online (Sandbox Code Playgroud)
  1. 如果没有任何东西被添加到上面的矢量或地图中,还是会分配一块缓冲存储器吗?(换句话说,缓冲区分配总是在容器创建期间发生,还是可以在调用push_back之类的函数之前推迟?)

  2. 是否存在处理初始STL容器缓冲区分配时间的标准,或者是否允许STL容器和编译器之间的行为不同?

注意:这个问题不是关于这样的容器会增加类Foo大小的额外字节.

(这个问题的一个相关子集强调分配大小是C++中向量的初始容量.)

kni*_*vil 8

C++参考使用C++ 17,默认构造函数是noexceptiff分配器构造noexcept.所以它取决于使用的分配器.在VS 2015中,标准构造函数是noexcept.

澄清:这意味着如果分配器为no,noexcept则不分配任何内存块.

对于你的第二个问题:相同的参考,它是O(1).

  • @SergeyA - 实际上他有一个观点.如果默认构造函数是`noexcept`,并且`allocator :: allocate`抛出 - 这意味着容器在构造时不能请求内存.因此,vector/map不能预分配内存,因为allcoation可以抛出,违反了`noexcept` (6认同)
  • 如果分配器每个默认值分配一个内存块,那么分配器的构造函数就不能是"noexcept",因为内存分配可能会因异常而失败. (3认同)
  • 当我重新考虑这一点时,"noexcept"与此无关.向量可以**尝试**来分配内存,只是从分配器中捕获任何异常,然后只传递预分配.有noexcept构造函数没有说precocoation任何东西,因为向量可以至少尝试并传递,而不会推出分配器异常 (3认同)

Ser*_*eyA 5

标准没有说明任何内容,但我特别注意的实现将做一些预先std::vector分配,并且不会预先分配任何东西std::map.

这实际上曾经让我困难,当我讨厌一个巨大的容器,哪些元素有一个微不足道 - 不超过10个元素,大多数条目有0大小的向量 - 矢量在其中.此实现中的默认向量容量为32,并且'32*sizeof(vector_element)*number_of_elements'恰好非常大.

  • 这是哪个实现?老实说,这听起来像是实现中令人难以置信的愚蠢行为。 (2认同)
  • 初始容量大于零的`std :: vector`似乎不太可能代表那里的大多数实现.我当然认为任何这样的实现都是错误的,即使标准允许它.我可以更宽容一些其他容器(例如,`std :: unordered_map`),但是矢量和字符串不应该进行不必要的动态分配. (2认同)