Reputation: 1975
I have read the documentation for C++ list iterators, but couldn't figure out one thing: are C++ iterators "safe"? I mean, does it stop incrementing once it reaches the last existing element in a list?
[]'s
Upvotes: 5
Views: 5434
Reputation: 1688
To answer your question, "No" they will not stop as the responsibility is on the owner to check bounds.
However, one can put the checks into a proxy iterator and enforce bounds checks. This is going to cost you though as most likely there will be a price to pay. Most of the std algorithms now have first/last for both input and output iterators( see std::copy( first_in, last_in, first_out, last_out ) and will check the bounds along with ones that do not take the end of the output as that is not always a valid operation(e.g. end of a stream isn't known until it happens)
You can write a iterator proxy that contains a copy of the iterator, the first position and the last position. Then check if it will go out of bounds on operator++, operator--, and when accessing members or dereferencing. It is almost the same work as writing a skeleton contianer and could be used as such. For a small example see Iterator Proxy Example and then in use Iterator Proxy Usage Example
Upvotes: 1
Reputation: 179789
No. Like many things in C++, the default is speed.
The rationale is that you can trade speed for safety later, but not vice versa.
Upvotes: 2
Reputation: 838106
No, they're not "safe" in that sense. It is possible to increment an iterator past the end. For all the iterators in the standard library doing this will result in undefined behaviour. You could define your own iterators that do behave in a safe way instead if you wanted to.
Upvotes: 13
Reputation: 8174
Using properly, iterators are very useful.
Therefore the question "Are C + + iterators safe" will depend on how it is used.
Note that the incorrect use of printf API can cause serious errors.
The implementation will it be safe to use or not.
Upvotes: -1
Reputation: 58677
What you're asking is does std::list::iterator
do bound-checking. The answer is no, it doesn't. This means the iterator is faster than otherwise. If you want bound-checking then you can wrap the iterator with a bound-checking iterator wrapper of your own.
But if you follow conventions when you use iterators then you will always know at compile time when an iterator is invalid, i.e., points at an invalid position. For instance:
std::list
then make sure you store the iterator erase()
returns to get a valid iterator pointing at the new valid position, just beyond the element erased.std::remove()
make sure you store the returned iterator so you know what are the new bounds of your container.This approach shifts the bound-checking issue aside while retaining the performance of iterators that don't need to bother with making sure the user doesn't shoot herself in the foot.
Upvotes: 9
Reputation: 2004
You must test whether it != list.end()
, and leave the loop if end was reached.
Upvotes: 3
Reputation: 72271
No. If you dereference a "past-the-end" iterator, you get Undefined Behavior.
Upvotes: 2