Reputation: 21443
I am attempting to use iterators to walk over a vector<char*>
in c++. I have built a dummy program that is supposed to start at the end, and step backward (toward the beginning, or rend()
) on a number >0, and forward (toward the end, or rbegin()
) on a number <0, and exit on 0. if the iterator has reached either of the ends and the user attempts to step further, it should repeat the element at that end and not move the iterator. My problem is that, rather than doing that, if the user tries to run over the end, I just get a segfault. here's my code:
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
int main(){
vector<char*> vect;
char* tmp;
for (int i=1; i<=5; i++){
tmp = new char[7];
sprintf(tmp, "hello%d", i);
vect.push_back(tmp);
}
vector<char*>::const_reverse_iterator it = vect.rbegin();
int a;
cin >> a;
while (a!=0){
if (a>0){
if (it < vect.rend()){
cout << *(++it) << endl;
} else{
cout << *it << endl;
}
} else{
if (it > vect.rbegin()){
cout << *(--it) << endl;
} else{
cout << *it << endl;
}
}
cin >> a;
}
return 0;
}
Can anyone identify the problem?
EDIT
I forgot that I made a minor change. my previous code did not populate tmp
in the initializing for loop. that has been fixed
Upvotes: 2
Views: 872
Reputation: 76245
Since the goal, effectively, is to not use the past-the-end position, I'd recast the problem: it needs two iterators, one pointing to the first element in the desired range, and one pointing to the last one. Then the mechanics become easy:
if (it != end)
++it;
cout << *it << endl;
Similarly, going the other direction:
if (it != begin)
--it;
cout << *it << endl;
Where begin and end are defined like this:
typedef vector<char*>::reverse_iterator iter;
iter begin = vect.rbegin();
iter end = --vect.rend(); // assumes that vect is not empty
Upvotes: 0
Reputation: 8594
The problem is that the rend
iterator points one item past the (reversed) end of sequence. Dereferencing it causes a segfault:
if (it < vect.rend()){
cout << *(++it) << endl;
} else{
cout << *it << endl; // <---- segfault
}
A minimal fix could be
if (it+1 < vect.rend())
{
cout << *(++it) << endl;
} else{
cout << *it << endl;
}
Upvotes: 7