2011-09-21 98 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/