德克 - 为什么"储备"不存在?

Deque - how come "reserve" doesn't exist?

本文关键字:不存在 储备 德克 为什么      更新时间:2023-10-16

标准STL vector容器有一个"reserve"函数,用于保留未初始化的内存,以便以后使用,以防止重新分配。

为什么另一个deque容器没有呢?

增大std::vector的尺寸可能代价高昂。当vector超出其保留空间时,必须将vector的全部内容复制(或移动)到更大的保留空间。

由于std::vector调整大小的成本很高,所以vector::reserve()存在。reserve()可以制备std::vector,在不超过其容量的情况下达到一定的尺寸。

相反,deque总是可以添加更多的内存,而不需要重新定位现有的元素。如果std::deque 可以 reserve()内存,则几乎没有明显的好处。

对于vectorstring,保留空间通过确保元素不需要复制/移动来防止后期插入(直到容量)使迭代器和对早期元素的引用无效。这种重新定位也可能代价高昂。

对于dequelist,前面的引用永远不会因为末尾的插入而失效,元素也不会被移动,所以不需要预留容量。

您可能认为对于vectorstring,保留空间也保证以后的插入不会抛出异常(除非构造函数抛出),因为不需要分配内存。您可能会认为相同的保证对其他序列也有用,因此deque::reserve可能有用途。对于vectorstring实际上没有这样的保证,尽管在大多数(所有?)实现中这是正确的。所以这不是reserve的预期目的。

引自c++参考

与std::vector不同,deque的元素不是连续存储的,典型的实现是使用一系列单独分配的固定大小的数组。
deque的存储会根据需要自动扩展和收缩。 deque的扩展比std::vector的扩展成本低,因为它不涉及将现有元素复制到新的内存位置。

Deque可以在任何它想要的地方分配新的内存,并且只指向它,不像vector需要一个连续的内存块来保存所有的元素。

只有vector有。deque不需要保留函数,因为元素不是连续存储的,在添加或删除元素时不需要重新分配和移动元素。

reserve意味着分配大块连续数据(如向量)。dequeue中没有任何暗示连续存储的东西——它通常更像一个列表(你会注意到它也没有'reserve'函数)。

因此,'reserve'函数是没有意义的。

有两种主要类型的内存:分配单个块的内存,如数组和向量,以及其成员捕获任何空白位置来填充的分布式内存。队列和链表结构属于第二种类型,它们具有一些特殊的实际优势,例如,与数组和向量相比,删除特定元素不会导致大量内存移动。因此,他们不需要事先预留任何空间,如果他们需要,他们只需要连接到tip

如果你的目标是对齐内存容器,你可以考虑实现这样的东西:

std::deque<std::vector> dv; //deque with dynamic size memory aligned vectors.
typedef size_t[N] Mem;
std::deque<Mem> dvf //deque with fixed size memory aligned vectors. Here you can store the raw bytes adding a header to loop through and cast using header information and typeid... 
//templates and polymorphism can help storing raw bytes, checking the type where a pointer points for example, and creating an interface to access the partial aligned memory.

或者,您可以使用map来访问vector,而不是deque…