2011-03-22 96 views
1

這個示例代碼是否有效?是一個迭代器vec.end()在vec.push_back()沒有重新分配時仍然有效

#include<vector> 
using namespace std; 

int main() { 
    vector<int> vec(10); // create with 10 elements 
    vec.reserve(100); // set capacity to 100 
    vector<int>::iterator iter = vec.end(); // points 1 past vec[9] 

    vec.push_back(777); 

    bool is_this_valid_and_true = *iter == vec[10]; // ? 

    // VS2010 runtime error in debug build: 
    // Expression: vector iterator not dereferencable 
    // Works in release build 

    iter = vec.end() + 1; // points 2 past vec[10]? 
    vec.push_back(888); 
    vec.push_back(999); 

    is_this_valid_and_true = *iter == vec[12]; // ? 
} 

VS2010中的錯誤可能與此有關 bug

如果我設置的命令行選項/D_HAS_ITERATOR_DEBUGGING=0或設置

#define _HAS_ITERATOR_DEBUGGING 0 
#include<vector> 

沒有錯誤。

編輯:

在尋找答案的方式,我覺得這應該代碼導致錯誤。編譯器中沒有錯誤。它只在釋放模式下工作,因爲迭代器被實現爲指針。

+0

沒有錯誤。有一個錯誤(它只是沉默,致命,並會在稍後的時間殺死你與飛行的鼻子惡魔)。 – 2011-03-22 20:11:36

回答

6

您正在考慮迭代器作爲指針。

迭代器可能使用指針作爲實現細節,但它們不是實際的指針。

因此:

iter = vec.end() + 1; // This is not valid. 

沒有這樣的東西作爲兩個元件傳遞的數據的末尾。

vec.end()返回一個迭代器,當遞減是對最後一個元素的引用時(假設有元素)。而增量時引用最後一個元素的迭代器等同於end()返回的迭代器。

// Note: Assuming vector iterators were not invalidated after an insert anyway. 
//  But for arguments sake lets play this out. 
// 
vector<int>::iterator iter = vec.end(); // points 1 past vec[9] 
vec.push_back(777); 
bool is_this_valid_and_true = *iter == vec[10]; // Not valid. 
               // This is the end() iterator 
               // de-referencing it is UB 

但去referenceing年底(),表示迭代是不確定的行爲()(即使你已經預留空間)(實施可能不使用指針來。例如一些調試STL實現會做迭代器代碼中廣泛的錯誤檢查)。

+0

謝謝。所以技巧'iter = vec.end(); iter--; vec_push_back(777); iter ++;'會使'iter'成爲現在最後一個元素的有效迭代器? – JohnPS 2011-03-22 19:46:09

+0

@JohnPS:只要沒有重新分配,是的。 – Erik 2011-03-22 19:53:57

+0

因此,爲了調試,我猜測編譯器會在插入過程中將'iterator()'標記爲無效。之後的任何修改或算術都會導致調試錯誤。感謝您的澄清。 – JohnPS 2011-03-22 20:06:31

7

23.2.4.3/1:

導致重新分配,如果新的大小比原來容量更大 。如果沒有 重新分配發生,所有 迭代器和引用之前 插入點保持有效。如果 除了 之外引發異常,T的拷貝構造函數或賦值 運算符沒有任何影響。

所以不,end()不必push_back後有效。該報價是關於vector.insert,push_back的定義依據insert

+0

感謝您參考標準。當我看時,我不知道在哪裏找到相關信息。 – JohnPS 2011-03-22 20:07:34