Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
668 views
in Technique[技术] by (71.8m points)

python - C++: push_back in std::vector while iterating it

Following code snippet provides a very weird output. I was expecting an overflow( Python gives a MemoryError)

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a{1,2,3};

    for( auto const & item : a)
        a.push_back(item);


    for( auto const & item : a)
        std::cout<<item<<',';

    return 0;
}

Output: 1,2,3,1,0,3,

How do I interpret this result?

If you do a similar thing in Python, it gives a memory error.

>>> a = range(0,20)
>>> for i in a:
    a.append(i)



Traceback (most recent call last):
  File "<pyshell#3>", line 2, in <module>
    a.append(i)
MemoryError

>>> 

This question came to my mind, because above way of writing code is considered to be bound-safe. And for bound safety container should not grow/shrink during foreach type iteration. So, this is a leaky abstraction.

Is there a way one can wrap this foreach loop so that any operation causing size-modification/reallocation is not allowed in the loop body.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In C++ adding elements to a vector may cause reallocation of the contained data, which will invalidate all iterators. That means you can't loop over the vector using iterators (which is what the range-based for loop does) while also inserting new elements.

You can however iterate using indexes and use the vector size as condition, since indexes will always be the same.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...