STL C++ 中的内存分配

Memory Allocation in STL C++

我对 STL C++ 中的内存重新分配有点困惑。例如,我知道如果我声明一个 vector,并继续将元素推回其中,向量将在某个时候需要重新分配内存 space 并将所有现有元素复制到其中。对于链表,不需要重新分配,因为元素不是连续存储在堆栈中的,每个元素使用一个指针指向下一个元素。

我的问题是,C++ 中的其他 STL 的情况如何?例如,stringmapunordered_map?他们需要重新分配吗?

(免责声明:标准可能不需要此处指定的所有具体数据结构,但记住它们有助于link将规则具体化)

std::string~=std::vector;它是一个动态数组,如果你在它的末尾继续推动元素,有时它会重新分配你的元素。

std::list:每个元素都是一个新的 linked 列表节点,因此无论您在哪里插入新元素,都不会发生重新分配。

std::deque:通常由几页元素组成;当页面已满时,将分配一个新页面并将其添加到页面列表中;出于这个原因,您的元素不会发生重新分配,如果您在开始或结束时继续推动内容,您的元素永远不会移动。

std::map/std::multimap/std::set/std::multiset:典型的二叉树,每个元素自己分配;从未执行过重新分配。

std::unordered_map/std::unordered_multimap/std::unordered_set/std::unordered_multiset:散列table;当 table 足够满时,会进行重新散列和重新分配。

几乎所有的 STL 容器内存都是在堆上分配的,即使是向量也是如此。普通数组和 std::array 模板是唯一一次可能在堆栈上有内存的情况。

如果您的问题是关于连续内存分配(无论是在堆栈上还是堆上),那么,可能是普通数组,std::array、std::vector 已经获得了连续内存。几乎所有其他容器,如 list、deque、map、set 等,都没有连续分配内存。