ewok
ewok

Reputation: 21443

vector iterator in c++

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

Answers (2)

Pete Becker
Pete Becker

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

Andriy
Andriy

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

Related Questions