TPOT94
TPOT94

Reputation: 128

Vector iterator not dereferencable in for loop

I'm using a loop to count how many times that a word was entered then print the word and how many times it was entered, which works but it never prints the last word, I have it sorted alphabetically. Before the last word is printed it errors out saying the iterator is not dereferencable. Here is my code for the loop:

for (vector<string>::iterator it = v.begin() ; it != v.end(); ++it)
    {
        if (*it == *(it+1))
        {
        count++;
        }
        else if (*it != *(it+1))
        {
                count++;
            cout << *it << " ---- " << count << endl;
            count=0;
        }
    }

Upvotes: 10

Views: 34647

Answers (5)

billz
billz

Reputation: 45410

Your code has undefined behavior - imagine it is pointing to the last element of v, then you are trying to dereference v.end() in *(it+1)

if (*it != *(it+1)

STL iterator, end doesn't point to last element; end() returns an iterator that represents the end of the elements in the container. The end is the position behind the last element. Such an iterator is also called a past-the-end iterator.

Thus, begin() and end() define a half-open range that includes the first element but excludes the last

 --------------------------------
 |  |   |   |   |   |   |   |   |
 --------------------------------
  /\                               /\      
begin()                            end() 

For what you are trying to achieve, have a look at std::adjacent_find

auto it = std::adjacent_find(v.begin(), v.end());

if (it != v.end())
{
  count ++;
}
else
{
   cout << *it << " ---- " << count << endl;
}

Upvotes: 21

Jarod42
Jarod42

Reputation: 217085

when it == v.end() - 1, you deference (it+1) so v.end(), and deference v.end() is undefined behaviour.

Upvotes: 2

Neil Kirk
Neil Kirk

Reputation: 21763

When it is one before the end iterator, you have a problem here: *(it+1) as this attempts to dereference the end iterator, which is invalid.

I'm not sure what you want your logic to do in this case, but you can check for this with if (it+1 != v.end()) before doing your stuff.

Upvotes: 1

Gorpik
Gorpik

Reputation: 11028

When you are at the last word and try to execute:

if (*it == *(it+1))

it+1 is pointing at v.end(), which is a valid iterator, but is not derefernceable. Hence the error.

Upvotes: 1

hate-engine
hate-engine

Reputation: 2350

Because when it is near end, it+1 is at end, and you trying to dereference it in if operator.

Upvotes: 0

Related Questions