2

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

2
  • You do know there is a memory leak in that code, right? Commented Aug 13, 2012 at 15:04
  • yea I saw that, but it doesnt really matter as this is just dumnmy code Commented Aug 13, 2012 at 15:17

2 Answers 2

7

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;   
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is correct, but it's a little difficult to see exactly where rend() is being dereferenced from a casual glance at the code. The suggested line should replace if(it < vect.rend()).
@Chad: Thank you, I added a clarification
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.