2015-09-26 98 views
1

我想了解向量中迭代器失效的概念。 從我已完成的一些閱讀中,我發現如果一個向量包含說7個元素,並且您刪除了第5個索引上的元素,則第5個元素向前的迭代器將失效。這是因爲第5個指數之後的所有元素都需要上移一個時隙。這對我來說很有意義但我有點以下兩種情況下如果迭代器在STL容器中失效,指針是否失效

std::vector<foo> vec {foo{1},foo{2}};    //foo is a simple class 
    foo* ptr = &vec[0];        //Case 1 
    std::vector<foo>::iterator it = vec.begin() + 1; //Case 2 

之間的混淆是可以安全地說,一個STL容器,如果一個迭代器變爲無效然後一個指針變得太無效?例如,如果it失效,那麼ptr也會失效?如果不是,你可以提供一個迭代器失效但指針保持有效的情況嗎?我目前對矢量,地圖和deques感興趣。

更新: 所以我寫了一些代碼,並嘗試

std::vector<foo> vec {foo{1},foo{2},foo{3}}; 
foo* ptr = &vec[1]; 
std::vector<foo>::iterator it = vec.begin() + 1; 
std::cout << "Before : " << ptr->a << "\n"; 
vec.erase(vec.begin() + 1); //Remove the second element 
std::cout << "Iterator value : " << it->a << "\n"; 
std::cout << "After : " << ptr->a << "\n"; 

結果是

Before : 2 
Iterator value : 3 
After : 3 

我很奇怪爲什麼矢量沒有提到的是,由於這個迭代器是無效的是元素被移除之前獲得的迭代器。

+0

這些向量運算無效的所有指針,迭代器和引用在矢量對象 –

+0

您可以通過思考,容器必須如何管理其緩衝區,緩衝區或對象,並應用該規則推理出關於無效大多數規則是,標準旨在允許有效的實施。 –

+0

重新指針,標準使用短語「迭代器和引用」,其中任何實際的解釋包括指針。這並不意味着所有這些指針都變成*無效指針*。通過擦除索引'i'處的單個項目,指針'&v [i]','&v [i + 1]'直到並且包括現在的最後一個項目,僅僅指代具有可能改變的值的對象上一個插槽,就像你說的那樣)。矢量的緩衝區保證是連續的,所以只要至少有一個指向它的指針仍然作爲指針有效,其他指針(在新的大小內)也必須作爲指針有效。 –

回答

1

當您刪除一個項目時,不同容器的行爲會有所不同。

http://en.cppreference.com

std::vector::erase

在或擦除,包括end()迭代器的點之後失效迭代器和引用。

std::map::erase

引用和迭代器擦除元件失效。其他引用和迭代器不受影響。

std::deque::erase

所有迭代器和引用被無效,除非擦除元件是在末端或所述容器的開始,在這種情況下,只有迭代器和引用到擦除元件失效。

+0

我剛剛更新了我的答案,你能告訴我爲什麼迭代器沒有失效嗎? –

+0

@JamesFranco,這是UB不幸的事情之一。代碼有時會以一種理智的方式行事。但是,在不同的編譯器,不同的優化標誌等中,它可能會很不一樣。 –

+0

UB代表什麼? –