简体   繁体   English

如果迭代器在STL容器中无效,指针是否会失效

[英]Does a pointer become invalidated if an iterator is invalidated in STL containers

I am trying to understand the concept of iterator invalidation in vectors. 我试图理解向量中迭代器无效的概念。 From some of the reading I have done I have found that if a vector contains say 7 elements and you delete the element on the 5th index then the iterators from 5th element onwards become invalidated. 从我所做的一些阅读中,我发现,如果一个向量包含说7个元素,并且您删除了第5个索引上的元素,那么从第5个元素开始的迭代器将变得无效。 This is because all the elements after the 5th index would need to move up one slot. 这是因为第5个索引之后的所有元素都需要向上移动一个插槽。 This makes sense to me however I am a bit confused between the following two cases 这对我来说很有意义,但是以下两种情况让我有些困惑

    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

Is it safe to say that for a STL container if an iterator becomes invalidated then a pointer becomes invalidated too ? 可以肯定地说,对于STL容器,如果迭代器无效,那么指针也无效? For instance if it becomes invalidated will ptr be invalid too ? 例如,如果it变得无效, ptr将无效吗? If not could you give a case in which an iterator becomes invalidated but a pointer remains valid ? 如果不能,您是否可以给出迭代器无效但指针仍然有效的情况? I am currently interested in vectors , maps and deques. 我目前对vectors,maps和deques感兴趣。

Update: So I wrote a little code and experimented 更新:所以我写了一些代码并进行了实验

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";

The result was 结果是

Before : 2
Iterator value : 3
After : 3

I am surprised why the vector did not mention that the iterator was invalid since this was the iterator obtained before an element was removed. 我很惊讶为什么向量没有提到迭代器是无效的,因为这是在删除元素之前获得的迭代器。

Different containers behave differently when you remove an item. 删除项目时,不同的容器行为不同。

From http://en.cppreference.com : http://en.cppreference.com

std::vector::erase

Invalidates iterators and references at or after the point of the erase, including the end() iterator. 在擦除点或擦除点之后使迭代器和引用无效,包括end()迭代器。

std::map::erase

References and iterators to the erased elements are invalidated. 对已删除元素的引用和迭代器无效。 Other references and iterators are not affected. 其他引用和迭代器不受影响。

std::deque::erase

All iterators and references are invalidated, unless the erased elements are at the end or the beginning of the container, in which case only the iterators and references to the erased elements are invalidated. 除非已删除的元素位于容器的末尾或开始,否则所有迭代器和引用都将无效,在这种情况下,仅迭代器和对已擦除元素的引用将无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM