tags:

views:

151

answers:

5

So when we need to traverse a container from start to end we write something like

for (i = v->begin(); i != v->end(); i++)

assuming i is an iterator for container v.

My question is "what guarantees that end will always point to one past the last element in container?" How does STL ensures this behavior and is there any chance that this case is not true?

+3  A: 

The stl specification guarantees that end will be one past the end See here. That will always be the case. Exactly how it does this can depend on the implementation (sometimes the values is just set to null for example), but rest assured your loop will be OK as long as v is a valid pointer.

JoshD
+1  A: 

"end will always point to one past the last element in container" means that if you increment iterator that points to the last element it will be equal to the result of end(). Implementation can be different. In Visual C++ std::vector::end() returns implementation specific iterator that holds zero pointer.

Kirill V. Lyadvinsky
I strongly doubt it, as `std::vector<T>::iterator` is a random-access iterator. If `std::vector<T>::end()` returned `(T*)0`, `end()-begin()` would be illegal, yet it needs to return `std::vector::size()`
MSalters
To be more correct: `end` returns implementation specific iterator that holds zero pointer.
Kirill V. Lyadvinsky
The part of *holding zero pointer* is, well, unneeded and imprecise. In gcc vector implementation, `vector<>::end()` is defined as `vector<>::begin()+vector<>::size()`, and is actually stored in the `vector<>` object (GCC vector is implemented by means of three pointers: *begin*, *end* and *end_of_capacity*, where `begin==end` if the vector is empty, `begin+size()==end` at all times and `end==end_of_capacity` if `size()==capacity()`. There are no *zero pointer* anywhere to be seen.
David Rodríguez - dribeas
@David Rodríguez, That was in "Implementation can be different." part of my answer. "zero pointer" is related to the Visual C++ implementation, not to gcc.
Kirill V. Lyadvinsky
+4  A: 

C++03 Section 23.1/7 says

begin() returns an iterator referring to the first element in the container.

end() returns an iterator which is the past-the-end value for the container.

If the container is empty, then begin() == end();

Prasoon Saurav
+11  A: 

STL ensures this behavior by always storing stuff like this:

vector

In the end (pun), it doesn't matter what end() is, as long as it's always end() (and, obviously, can't be confused with any other node).

David Titarenco
Mate, you get +1 just for the funky graphics :-)
paxdiablo
Paint FTW, I'd say :)
Matteo Italia
Doesn't the quote below from the C++ standard invalidate this answer? especially the graphic.
anand.arumug
A: 

You're asking about all STL containers... not a word of mention of vector specifically where end() might be implemented as you obviously intuitively expect. What's one past the end in a std::map<>? The "end is one past the last used node" thing is just a logical concept, expressing that you can safely increment from that last-used node, differentiate/equate it from/to the abstract concept of "end", and do some node arithmetic where end is considered to be one further along than the last-used node. Don't take it too literally.

Tony