GCC实现中用于std :: string和std :: vector的重新分配策略是什么?
我对所采用的具体策略感兴趣:当我将项目附加到向量(或字符串的字符)时,它可能会超出保留的大小,然后会发生重新分配,但新的大小将作为一个函数旧的?在删除元素的情况下,实际重新分配和释放内存的阈值是多少(再次是新大小)?
其他编译器的答案也将受到赞赏。
答案 0 :(得分:4)
查看_M_check_len
中的bits/stl_vector.h
函数。它包含:
const size_type __len = size() + std::max(size(), __n);
因此,附加n个元素时的基本策略是大小加倍或增加n,以最大者为准。 pop_back
永远不会解除分配。 libc ++(LLVM)完全相同。
阅读代码是你找到字符串,释放等策略的唯一方法。
答案 1 :(得分:4)
vector
和string
都保证push_back
的复杂性是“摊销常数”,这意味着调用push_back
n所需的时间当 n 变大时,em>次除以 n 受一个常数限制。实现这一目标的唯一方法是重新分配以几何方式增加尺寸,即使新容量与旧尺寸的固定倍数相等。这样你只需要很少的“重新分配”。
实现中的典型增长因子是2或1.5,但任何严格大于1的数字都可以。
但这并不与reserve
互动。如果您在每次回送之前致电reserve(size() + 1)
,则每次都可能会重新分配。
答案 2 :(得分:1)
的确切reserve
的所有投注都已关闭。你使用它是这样的:
std::vector<T> myV;
myV.reserve(<space known to be needed>);
所以你知道{<1}}将不会被调用(也不会进行任何重新分配),直到 超出该空间。
答案 3 :(得分:1)
std :: vector有方法大小和容量。编写一个确定内存分配方式的简单程序应该不会太困难。策略可能会随着每个实现而变化,甚至可能随版本而变化。
我所看到的一个策略是使用增加的增量,这是一种自适应策略:为饥饿者提供更多食物以避免频繁改变数据。但增加的因素可供讨论。简单的复制可能会变得太快。
<强>后来强>
好奇自己,我写了那个程序。这是输出(g ++ 4.3.3):
capacity from 0 to 1 increased by 1 at size 1
capacity from 1 to 2 increased by 1 at size 2
capacity from 2 to 4 increased by 2 at size 3
capacity from 4 to 8 increased by 4 at size 5
capacity from 8 to 16 increased by 8 at size 9
capacity from 16 to 32 increased by 16 at size 17
capacity from 32 to 64 increased by 32 at size 33
capacity from 64 to 128 increased by 64 at size 65
capacity from 128 to 256 increased by 128 at size 129
capacity from 256 to 512 increased by 256 at size 257
capacity from 512 to 1024 increased by 512 at size 513
capacity from 1024 to 2048 increased by 1024 at size 1025
capacity from 2048 to 4096 increased by 2048 at size 2049
capacity from 4096 to 8192 increased by 4096 at size 4097
capacity from 8192 to 16384 increased by 8192 at size 8193
capacity from 16384 to 32768 increased by 16384 at size 16385
capacity from 32768 to 65536 increased by 32768 at size 32769
capacity from 65536 to 131072 increased by 65536 at size 65537
capacity from 131072 to 262144 increased by 131072 at size 131073
capacity from 262144 to 524288 increased by 262144 at size 262145
capacity from 524288 to 1048576 increased by 524288 at size 524289
在构造函数中使用初始分配会导致相同的进展,使用初始值而不是1。