2012-08-13 5 views
2

J'essaie d'utiliser des itérateurs pour parcourir un vector<char*> en C++. J'ai construit un programme factice qui est censé commencer à la fin, et reculer (vers le début, ou rend()) sur un nombre> 0, et en avant (vers la fin, ou rbegin()) sur un < 0, et quitter sur 0. si l'itérateur a atteint l'une ou l'autre des extrémités et que l'utilisateur tente d'aller plus loin, il doit répéter l'élément à cette fin et ne pas déplacer l'itérateur. Mon problème est que, plutôt que de le faire, si l'utilisateur essaie de dépasser la fin, je reçois juste un segfault. voici mon code:itérateur vectoriel en C++

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

Quelqu'un peut-il identifier le problème?

EDIT

J'ai oublié que je fait un changement mineur. mon code précédent n'a pas rempli tmp dans la boucle d'initialisation. cela a été corrigé

+0

Vous ne savez qu'il ya une fuite de mémoire dans ce code, non? – Fiktik

+0

oui j'ai vu cela, mais ce n'est pas vraiment important car c'est juste dumnmy code – ewok

Répondre

7

Le problème est que l'itérateur rend pointe un élément après la fin (inverse) de la séquence. Déréférencement il provoque une erreur de segmentation:

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

Un correctif minimal pourrait être

if (it+1 < vect.rend()) 
{ 
    cout << *(++it) << endl; 
} else{ 
    cout << *it << endl; 
} 
+0

Ceci est correct, mais il est un peu difficile de voir exactement où _ 'déchire()' est déréférencé à partir d'un coup d'œil au code. La ligne suggérée devrait remplacer 'if (it Chad

+0

@Chad: Merci, j'ai ajouté une clarification – Andrey

0

Depuis le but, effectivement, est de ne pas utiliser la position passé, la fin, je refondre le problème: il a besoin de deux itérateurs, un pointant vers le premier élément de la gamme désirée et un pointant vers le dernier. Ensuite, la mécanique devient facile:

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

De même, aller dans l'autre direction:

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

Où commencent et se terminent sont définis comme suit:

typedef vector<char*>::reverse_iterator iter; 
iter begin = vect.rbegin(); 
iter end = --vect.rend(); // assumes that vect is not empty