2011-09-21 103 views
1

我遇到了矢量容器的问题。我正试图提高将大量元素插入到一个向量中的性能。C++在矢量的末尾插入元素

基本上我用载体::储备,扩大我的矢量_children如果需要的话:

if (_children.capacity() == _children.size()) 
{ 
    _children.reserve(_children.size() * 2); 
} 

,并使用矢量::在()在_children而不是向量的末尾插入一个新的元素::的push_back():

_children.at(_children.size()) = child; 

_children具有已经在它的一个元件,所以第一个元件应在位置1处被插入,并在该时的容量为2

尽管这样,一个out_of_range错误被抛出。有人可以向我解释,我在这里误解了什么?即使选择的位置小于矢量容量,是否可以插入额外的元素?如果需要,我可以发布一些更多的代码。

在此先感谢。

/mads

+1

你的编译器实现的'需要更多时VECTOR'可能已经双打分配的内存。 'reserve'更适用于在添加任何数据之前知道向量大小的上限。 – aschepler

+0

你好,马兹。欢迎来到Stack Overflow。不要忘记阅读[faq](http://stackoverflow.com/faq)。并且,请提供帮助您的任何答案,并在解决问题时接受答案。 –

回答

8

增加容量不会增加向量中元素的数量。它只是确保矢量能够增长到所需的大小,而不必重新分配内存。即,您仍然需要拨打push_back()

请注意,呼叫reserve()以几何形式增加容量是浪费精力。 std::vector已经这样做。

+0

如果可以的话,我会+2,因为这两段都是正确的,需要说。 –

+0

当然你是对的。我不知道我在想什么。谢谢 – madshov

1

这会导致访问超出限制。保留内存不会影响矢量的大小。

基本上,你正在手动做什么push_back在内部做。你为什么认为它会更有效率?

1

既不at也不reserve增加向量的大小(后者增加容量但不是大小)。

此外,您尝试的优化几乎肯定是多余的;您应该简单地将push_back元素放入阵列并依靠std::vector以智能方式扩展其容量。

0

你有能力大小区分。您只能在大小内分配,并且保留仅影响容量。

1

这不是at()的用途。 at()[]的检查版本,即访问元素。但是reserve()不会更改元素的数量。

您应该只使用reserve()后跟push_backemplace_backinsert(在结尾处);所有这些都将是有效的,因为如果你停留在容量限制之下,它们不会导致重新分配。

请注意,矢量已经的行为与您手动完全相同:当它达到容量时,它将分配的内存大小调整为当前大小的倍数。这是由添加元素具有分期恒定时间复杂度的要求所规定的。

0

vector::reserve仅在内部预留空间,但不构建对象,也不会更改矢量的外部大小。如果您使用储备,您需要使用push_back。 此外​​范围检查,这使得它比vector::operator[]慢很多。

你正在做的是试图模仿内部已经实现的行为向量的一部分。每次空间耗尽时,它的尺寸将扩大一定的因数(通常约为1.5或2)。如果你知道你正在推回许多对象和只想要一个重新分配使用:

vec.reserve(vec.size() + nbElementsToAdd); 

如果没有添加足够的元素,这是潜在的比vector默认行为恶化。

0

矢量的容量不是它所具有的元素的数量,而是它可以容纳的元素的数量,而不需要分配更多的内存。容量等于或大于向量中元素的数量。

在您的示例中,_children.size()为1,但位置1上没有元素。您只能使用赋值来替换现有元素,而不能添加新元素。根据定义,最后一个元素是_children.at(_children.size()-1)

正确的方法是使用push_back(),它是高度优化的,比在索引处插入更快。如果您事先知道要添加多少元素,您当然可以使用reserve()作为优化。

不需要手动调用保留,因为如果需要,vector会自动调整内部存储的大小。其实我相信你在你的例子中所做的是类似于矢量在内部所做的 - 当它达到容量时,保留两倍的当前大小。

又见http://www.cplusplus.com/reference/stl/vector/capacity/