Mauren
Mauren

Reputation: 1975

Are C++ iterators "safe"?

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

Answers (7)

Beached
Beached

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

MSalters
MSalters

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

Mark Byers
Mark Byers

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

lsalamon
lsalamon

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

wilhelmtell
wilhelmtell

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:

  • When you erase an element from a 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.
  • When you call 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

Christoph
Christoph

Reputation: 2004

You must test whether it != list.end(), and leave the loop if end was reached.

Upvotes: 3

aschepler
aschepler

Reputation: 72271

No. If you dereference a "past-the-end" iterator, you get Undefined Behavior.

Upvotes: 2

Related Questions