2

vector<char*>イテレータを使用してC++でaをウォークオーバーしようとしています。私は、最後から開始し、0より大きい数で後方(先頭または)に進み、 0未満の数値rend()で前方(最後または)に進み、0で終了することになっているダミープログラムを作成しました。 rbegin()。イテレータがいずれかの端に到達し、ユーザーがさらにステップしようとした場合、イテレータを移動せずに、その端で要素を繰り返す必要があります。私の問題は、それを行うのではなく、ユーザーが最後まで実行しようとすると、セグメンテーション違反が発生することです。これが私のコードです:

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

誰かが問題を特定できますか?

編集

小さな変更を加えたことを忘れました。tmp以前のコードは、初期化forループに入力されませんでした。修正されました

4

2 に答える 2

7

問題は、rendイテレータがシーケンスの(逆にされた)終わりを過ぎた1つのアイテムを指すことです。それを逆参照すると、セグメンテーション違反が発生します。

    if (it < vect.rend()){
        cout << *(++it) << endl;
    } else{
        cout << *it << endl;    // <---- segfault
    }

最小限の修正は

if (it+1 < vect.rend())
{
    cout << *(++it) << endl;
} else{
    cout << *it << endl;   
}
于 2012-08-13T14:54:30.783 に答える
0

目標は、事実上、終了後の位置を使用しないことであるため、問題を再キャストします。1つは目的の範囲の最初の要素を指し、もう1つは最後の要素を指す2つのイテレーターが必要です。その後、メカニズムが簡単になります。

if (it != end)
    ++it;
cout << *it << endl;

同様に、反対方向に進みます。

if (it != begin)
    --it;
cout << *it << endl;

開始と終了は次のように定義されます。

typedef vector<char*>::reverse_iterator iter;
iter begin = vect.rbegin();
iter end = --vect.rend();  // assumes that vect is not empty
于 2012-08-13T15:56:26.637 に答える