Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::vector和std::string重新分配策略_C++_Gcc_Stl - Fatal编程技术网

C++ std::vector和std::string重新分配策略

C++ std::vector和std::string重新分配策略,c++,gcc,stl,C++,Gcc,Stl,在GCC的实现中,std::string和std::vector的重新分配策略是什么 我对所采用的具体策略感兴趣:当我将项附加到向量(或将字符附加到字符串)时,它可能会超过保留的大小,然后会发生重新分配,但作为旧大小的函数,新大小是什么?在删除元素的情况下,实际重新分配和释放内存的阈值是多少(新的大小又是多少) 对于其他编译器的答案也将不胜感激。所有关于reserve工作原理的赌注都已取消。您可以这样使用它: std::vector<T> myV; myV.reserve(<s

在GCC的实现中,std::string和std::vector的重新分配策略是什么

我对所采用的具体策略感兴趣:当我将项附加到向量(或将字符附加到字符串)时,它可能会超过保留的大小,然后会发生重新分配,但作为旧大小的函数,新大小是什么?在删除元素的情况下,实际重新分配和释放内存的阈值是多少(新的大小又是多少)

对于其他编译器的答案也将不胜感激。

所有关于
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);