Public Group

# C++ Iterator Problem

This topic is 4343 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I was practicing using iterators, and I make this simple program, it works, but when I change one thing, when I compile it, it doesnt gernerate an error, but a message box pops up and says, "vector iterator not dereferencable". The reason I changed what I did was to make the vector count backwards. This doesnt sound like it would make an error, but I guess I was wrong. Can someone help me with this? Also, In my book it expalins that all STL components live in the std namepsace, so by using 'using namespace std', i can refer to algorithms without typing std in the declaration, but in my code, i donnot put std:: infornt of any of the algorithms (sort basically), and it doesnt generate an error, and it works, can someone please help me understand why? Error Free Source Code:
#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
int i = 0;

std::vector<int> high_scores;
high_scores.push_back(64003);
high_scores.push_back(34567);
high_scores.push_back(99999);
high_scores.push_back(56211);

std::vector<int>::const_iterator cIter;

std::cout << "High Scores:\n\n";
sort(high_scores.begin(), high_scores.end());
for(cIter = high_scores.begin(); cIter != high_scores.end(); ++cIter)
{
i++;
std::cout << i << ": " << *cIter << std::endl;
}

i = 0;
std::cout << "\nNew High Score!\n\n";
high_scores.insert(high_scores.begin(), 898005);
sort(high_scores.begin(), high_scores.end());

for(cIter = high_scores.begin(); cIter != high_scores.end(); ++cIter)
{
i++;
std::cout << i << ": " << *cIter << std::endl;
}

std::cout << "\nPress Enter to Exit High Scores.";
std::cin.get();

return 0;
}


Error Source Code:
// What I changed was the for loops. I changed the "for(cIter =
// high_scores.begin(); cIter != high_scores.end() ++cIter)" to "for(cIter =
// high_scores.end(); cIter != high_scores.begin(); --cIter)"

#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
int i = 0;

std::vector<int> high_scores;
high_scores.push_back(64003);
high_scores.push_back(34567);
high_scores.push_back(99999);
high_scores.push_back(56211);

std::vector<int>::const_iterator cIter;

std::cout << "High Scores:\n\n";
sort(high_scores.begin(), high_scores.end());
for(cIter = high_scores.end(); cIter != high_scores.begin(); --cIter)
{
i++;
std::cout << i << ": " << *cIter << std::endl;
}

i = 0;
std::cout << "\nNew High Score!\n\n";
high_scores.insert(high_scores.begin(), 898005);
sort(high_scores.begin(), high_scores.end());

for(cIter = high_scores.end(); cIter != high_scores.begin(); --cIter)
{
i++;
std::cout << i << ": " << *cIter << std::endl;
}

std::cout << "\nPress Enter to Exit High Scores.";
std::cin.get();

return 0;
}



##### Share on other sites
The problem is that .end() doesn't point to a node, meaning it is pointing to nothing (so it can't be dereferenced.) Another problem with your code is that you won't get the first node. What you need to use is the reverse iteration functions:
for(cIter = high_scores.rbegin(); cIter != high_scores.rend(); ++cIter){	i++;	std::cout << i << ": " << *cIter << std::endl;}

HTH!

##### Share on other sites
The iterator returned by end refers to the element just after the last one in the list, so it cannot be dereferenced. If you decrement it before you dereference it, it may work. However, I believe the vector class has a reverse iterator that can be accessed via rbegin and rend, which would be easier to use.

##### Share on other sites
Of course you must declare cIter to be of type reverse_iterator rather than iterator. Rawr.

##### Share on other sites
Quote:
 Original post by Programmer16The problem is that .end() doesn't point to a node, meaning it is pointing to nothing (so it can't be dereferenced.) Another problem with your code is that you won't get the first node. What you need to use is the reverse iteration functions:for(cIter = high_scores.rbegin(); cIter != high_scores.rend(); ++cIter){ i++; std::cout << i << ": " << *cIter << std::endl;}HTH!

I tried this, but it generated an error saysing, "error C2679: binary '!=' : no operator found which takes a right-hand operand of type 'std::reverse_iterator<_RanIt>' (or there is no acceptable conversion)"

What I did try this on is on sort(). I did this:

sort(high_scores.rbegin(), high_scores.rend());

That worked. Thanks for the help everyone! [smile]

BTW, what is a node?

##### Share on other sites
Quote:
 Original post by DeyjaOf course you must declare cIter to be of type reverse_iterator rather than iterator. Rawr.

I thought so, but I couldn't find a declaration for reverse_iterator, so I figured I was wrong. Thanks for the info!

Quote:
Original post by NUCLEAR RABBIT
Quote:
 Original post by Programmer16The problem is that .end() doesn't point to a node, meaning it is pointing to nothing (so it can't be dereferenced.) Another problem with your code is that you won't get the first node. What you need to use is the reverse iteration functions:for(cIter = high_scores.rbegin(); cIter != high_scores.rend(); ++cIter){ i++; std::cout << i << ": " << *cIter << std::endl;}HTH!

I tried this, but it generated an error saysing, "error C2679: binary '!=' : no operator found which takes a right-hand operand of type 'std::reverse_iterator<_RanIt>' (or there is no acceptable conversion)"

What I did try this on is on sort(). I did this:

sort(high_scores.rbegin(), high_scores.rend());

That worked. Thanks for the help everyone! [smile]

Yea, my fault. Sorry! You need to delcare your iterator as reverse_iterator. Thanks Deyja!

Quote:
 Original post by NUCLEAR RABBITBTW, what is a node?

I use 'node' as a reference to a point that contains data. In your example it would be an integer. In a string, each character would be a node. (Sorry if this confuses you =/.)

##### Share on other sites
Visual Representation:
+----------+---------+-------------+-------------+-------------+-------+| Iterator | begin() | begin() + 1 | begin() + 2 | begin() + 3 | end() |+----------+---------+-------------+-------------+-------------+-------+| Value    | 64003   | 34567       | 99999       | 56211       | NULL  |+----------+---------+-------------+-------------+-------------+-------+|                                                                      ||                           high_scores                                ||                                                                      |+----------------------------------------------------------------------+

(I used "NULL" to make it visible that end() is pointing to nothing.)

YaY for AsCiI ArT!

I just think that visual representations makes things easy, atleast for me they do.

[Edited by - agi_shi on July 4, 2006 6:04:52 PM]

##### Share on other sites
Quote:
 Original post by agi_shiVisual Representation:+----------------------------------------------------------------------+| Iterator | begin() | begin() + 1 | begin() + 2 | begin() + 3 | end() |+----------+---------+-------------+-------------+-------------+-------+| Value | 64003 | 34567 | 99999 | 56211 | NULL |+----------------------------------------------------------------------+| || high_scores || |+----------------------------------------------------------------------+(I used "NULL" to make it visible that end() is pointing to nothing.)YaY for AsCiI ArT!I just think that visual representations makes things easy, atleast for me they do.

Helps me too [smile]. Thanks man

##### Share on other sites
Quote:
 Original post by NUCLEAR RABBITWhat I did try this on is on sort(). I did this:sort(high_scores.rbegin(), high_scores.rend());That worked. Thanks for the help everyone! [smile]

Naturally, that sorts the list backwards instead of iterating over it backwards - with the same net result.

Of course, you could also do that by specifying the opposite comparison for sorting:

sort(high_scores.begin(), high_scores.end(), std::greater<int>);

• 9
• 9
• 13
• 41
• 15