C++ std::vector和std::string重新分配策略
在GCC的实现中,std::string和std::vector的重新分配策略是什么 我对所采用的具体策略感兴趣:当我将项附加到向量(或将字符附加到字符串)时,它可能会超过保留的大小,然后会发生重新分配,但作为旧大小的函数,新大小是什么?在删除元素的情况下,实际重新分配和释放内存的阈值是多少(新的大小又是多少) 对于其他编译器的答案也将不胜感激。所有关于C++ std::vector和std::string重新分配策略,c++,gcc,stl,C++,Gcc,Stl,在GCC的实现中,std::string和std::vector的重新分配策略是什么 我对所采用的具体策略感兴趣:当我将项附加到向量(或将字符附加到字符串)时,它可能会超过保留的大小,然后会发生重新分配,但作为旧大小的函数,新大小是什么?在删除元素的情况下,实际重新分配和释放内存的阈值是多少(新的大小又是多少) 对于其他编译器的答案也将不胜感激。所有关于reserve工作原理的赌注都已取消。您可以这样使用它: std::vector<T> myV; myV.reserve(<s
reserve
工作原理的赌注都已取消。您可以这样使用它:
std::vector<T> myV;
myV.reserve(<space known to be needed>);
std::vector myV;
myV.reserve();
因此,您知道在超出该空间之前,不必调用
reserve
(也不必执行任何重新分配)。std::vector具有方法大小和容量。编写一个确定内存分配方式的简单程序应该不会太困难。策略可能会随着每个实现而变化,甚至会随着版本的不同而变化
我见过的一种策略是使用递增的增量,这是一种适应性策略:给饥饿的人更多的食物,以避免频繁的数据混乱。但增长的因素有待讨论。简单的复制可能增长过快
以后
出于好奇,我写了那个程序。以下是输出(g++4.3.3):
在构造函数中使用初始分配会产生相同的级数,使用初始值而不是1。查看
bits/stl\u vector.h
中的函数\u M\u check\u len
。它包括:
const size_type __len = size() + std::max(size(), __n);
因此,添加n个元素时的基本策略是将大小增加一倍或增加n,以最大值为准<代码>弹出返回从不解除分配。libc++(LLVM)也做了同样的事情
阅读代码是找到字符串、解除分配等策略的唯一方法。矢量
和字符串都保证了推回的复杂性是“摊销常数”,这意味着调用push_back
n次除以n所需的时间在n变大时由一个常数限定。实现这一点的唯一方法是重新分配以几何方式增加容量,即使新容量成为旧容量的固定倍数。这样,您将只有很少的重新分配
实现中的典型增长因子是2或1.5,但任何严格大于1的数字都可以
不过,这不会与reserve
交互。如果您在每次回推之前调用reserve(size()+1)
,您每次可能都会得到重新分配。为了澄清这个问题(根据@Paul的解决方案),我对如何避免重新分配不感兴趣,但想了解实现所使用的策略。仅供参考,您可以在线浏览libstdc++源代码,例如
const size_type __len = size() + std::max(size(), __n);