5

我有一个包含 1000 个“节点”的向量

 if(count + 1 > m_listItems.capacity())
     m_listItems.reserve(count + 100);

问题是当我要重新填充它时,我也将其清除。

m_listItems.clear();

容量不变。我使用了 resize(1); 但这似乎并没有改变容量。那么如何改变储备呢?

4

5 回答 5

20
vector<Item>(m_listItems).swap(m_listItems);

将再次缩小m_listItemshttp ://www.gotw.ca/gotw/054.htm (Herb Sutter)

如果你想清除它,用一个空向量交换:

vector<Item>().swap(m_listItems);

这当然更有效。(请注意,交换向量基本上意味着只交换两个指针。没有什么真正耗时的事情)

于 2008-11-25T23:52:57.213 回答
2

您可以按照其他人的建议交换矢量,并且如http://www.gotw.ca/gotw/054.htm中所述,但请注意它不是免费的,您正在执行每个元素的副本,因为vector 必须分配一个新的、更小的内存块,并复制所有旧内容。(交换操作本质上是免费的,但是您正在交换一个临时初始化的原始向量数据的副本,这不是免费的)

如果您事先知道向量有多大,则应从一开始就分配正确的大小,因此无需调整大小:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements

而且,如果您事先不知道容量,那是否浪费一点空间又有什么关系呢?是否值得花时间将每个元素复制到一个新的更小的向量(这就是 std::vector(v).swap(v) 会做的),只是为了节省几千字节的内存?

同样,当您清除向量时,如果您仍然打算重新填充它,将其容量设置为零似乎是一种令人印象深刻的时间浪费。

编辑

baash05:如果你有 1000000 件物品和 10 兆的 ram。你会说减少开销很重要吗?

不可以。调整矢量的大小暂时需要更多内存,因此如果您的内存有限,则可能会破坏您的应用程序。(您必须先将原始向量临时向量保存在内存中,然后才能交换它们,因此您最终会使用最多两倍的 RAM)。之后,您可能会节省少量内存(最多几 MB),但这没关系,因为向量中的多余容量永远不会被访问,所以它会被推送到页面文件,所以不会首先计入您的 RAM 限制。

如果您有 1000000 个项目,那么您应该首先将向量初始化为正确的大小。

如果你不能做到这一点,那么你通常最好不要管这个容量。特别是由于您声明要重新填充向量,因此您绝对应该重用已经分配的容量,而不是不断地分配、重新分配、复制和释放所有内容。

你有两种可能的情况。您要么知道需要存储多少元素,要么不知道。如果您知道,那么您可以首先创建具有正确大小的向量,因此您永远不需要调整它的大小,或者您不知道,然后您还不如保留多余的容量,所以至少它重新填充矢量时不必向上调整大小。

于 2008-11-26T00:13:21.430 回答
1

你可以从这里尝试这种技术

std::vector< int > v;
// ... fill v with stuff...
std::vector< int >().swap( v );
于 2008-11-25T23:51:50.897 回答
1

您可以swap使用具有所需容量的新向量。

vector< int > tmp;
old.swap( tmp );
于 2008-11-25T23:52:23.110 回答
1

据我所知,您不能将向量重新分配到比以往更低的容量。你只能分配更大的。这有充分的理由;其中之一是重新分配过程的计算量非常大。如果您真的需要更小的向量,请释放旧向量并创建一个更小的新向量。这实际上在计算上比让向量实际调整更小要简单得多。

于 2008-11-25T23:53:12.233 回答