Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I check a C++ iterator against null?

I'm having trouble with vector iterators. I've read in a few places that checking for null iterators isn't possible, and that the usual way to check iterators is to check it against vector.end() after a search. So for example:

vector< Animal* > animalList;

vector<Animal*>::iterator findInList(const type_info& type)
{
    // Loop through list of Animals, if Dog found, return iterator to it
}

auto it = findInList(typeid(Dog));
// With a pointer I can check if it's null, but with an iterator I have to check against animalList.end();

The problem is that the container could be empty. With an iterator I can't return null to indicate the container's empty or the search failed. I can return vector::end(), but cplusplus.com says:

If the container is empty, vector::end() function returns the same as vector::begin()

and then for vector::begin() it says:

If the container is empty, the returned iterator value shall not be dereferenced.

So if I have an empty container, vector::end() and vector::begin() point to the same place, I don't think I can dereference it, and I'm not even sure it's pointing to allocated memory.

Edit: Thanks to everyone. As you have iterated out, vector::end() or vector::begin() do not dereference the iterator, I can safely check against vector::end().

like image 683
Zebrafish Avatar asked Dec 27 '16 22:12

Zebrafish


People also ask

How do I check if an iterator is not null?

No, you can't check against NULL because it is not a pointer. Return and also check against animalList. end() . Only when the iterator is not equal to end() should you dereference it.

How do I know if my iterator is invalid?

use erase with increment : if (something) l. erase(itd++); so you can test the validity of the iterator.

What invalidates an iterator?

Iterator Invalidation in C++ When the container to which an Iterator points changes shape internally, i.e. when elements are moved from one position to another, and the initial iterator still points to the old invalid location, then it is called Iterator invalidation. One should be careful while using iterators in C++.

Can we compare iterators?

we can use == and != to compare to valid iterators into any of the library containers. The section also tells us that iterators for string and vector support relational operators (aka iterator arithmetic) which include >, >=, <, <=.


1 Answers

You don't need to check if the iterator is null, because it will never be. You need to check if the returned iterator is different from the container's end() position. If it is, you can safely dereference the iterator by *it.

If the container is empty, the returned iterator value shall not be dereferenced. So if I have an empty container, vector::end() and vector::begin() point to the same place, I don't think I can dereference it, and I'm not even sure it's pointing to allocated memory.

No, checking if(myIt != container.end()) is not dereferencing the iterator. Iterator dereferencing is done via *myIt, which means getting the value of the object that the iterator is pointing to. It's always safe to check iterators to other iterators from the same container, it's unsafe to dereference iterators not pointing to containers' elements.

like image 141
paweldac Avatar answered Oct 26 '22 09:10

paweldac