简体   繁体   中英

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

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;   
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM