2010-01-22 69 views
2

我在C++編程語言閱讀:特別版不使用迭代器已調整大小的矢量

Don't use iterators into a resized vector

考慮這個例子。

vector<int>::iterator it = foo.begin(); 

while (it != foo.end()) { 
    if (// something) { 
    foo.push_back(// some num); 
    } 
    ++it; 
} 

這有問題嗎?在矢量調整大小之後,循環條件中的foo.end()會向前推1嗎?

P.S.另外,如果向量爲x個整數預留了空間,該怎麼辦?如果push_back沒有違反這個空間,它會不會是一個問題(我會假設如果it.end()指向一個超過vector中包含某個元素的最後一個元素)。

回答

5

是的,它有問題。

push_back的任何調用都有可能使所有迭代器失效爲一個向量。

foo.end()將始終檢索有效的結束迭代器(它可能與上次返回的值foo.end()不同),但it可能已失效。這意味着遞增或比較它可能會導致未定義的行爲。

+0

如果矢量的大小適合10個整數,該怎麼辦?假設push_back沒有超過這個預分配的大小,它是否仍然使迭代器無效? – Anonymous 2010-01-22 20:42:22

+0

@Person:嚴格地說,如果'push_back'不會導致向量的size()超出之前在調用reserve時給出的請求容量,那麼你可以保證對'push_back'的調用不會導致重新分配並且不會使迭代器失效到對象。不過,你仍然需要調用'end()'來獲得正確的'end()'。 – 2010-01-22 20:45:09

+0

謝謝。我認爲最好不要用預留空間和迭代器跳舞,而應該在這種情況下使用數組索引。 – Anonymous 2010-01-22 20:47:52

1

是的,存在問題。無論foo.end()it可能會被push_back()無效。編輯:(即它不是只是,結束可能會改變;有可能整個向量的緩衝區可能被重新分配,所以迭代器全部變得無效)。

1

是的,這有一個問題。 push_back會使您調用的矢量的任何迭代器失效。因此在撥打push_back後,執行++it甚至不合法。這是一個未定義的行爲,所以它有時可能會起作用,有時可能會失敗,但不應該依賴它的工作。

0

正如其他人所說,push_back()可能會使向量的所有迭代器無效。其原因是矢量中的數據存儲在連續內存區域中。如果push_back()或任何其他調整向量大小的操作都會導致向量的大小超出分配區域的容量,該區域將被重新分配並最終放在內存中的不同位置,而所有迭代器仍然會引用舊的內存區域。