2010-10-22 27 views
1

J'ai une erreur (incompatibilité de l'itérateur vectoriel) lors de l'exécution dans mon programme C++ que je ne comprends pas. [(Windows/Visual C++ 2008 Express)]std :: incompatibles de l'itérateur vectoriel

Voici une version simplifiée de mon problème:

#include <vector> 

class A 
{ 
    int mySuperInt; 
public: 
    A(int val) : mySuperInt(val) {} 
}; 
class B 
{ 
    std::vector<A*> myAs; 
    public: 
     B() 
     { 
      myAs.push_back(new A(1)); 
     }; 
     const std::vector<A*> getA() const {return myAs;} 
}; 

int main() 
{ 
    std::vector<B>* myBs = new std::vector<B>; 

    myBs->push_back(B()); 

    std::vector<B>::const_iterator it_B = myBs->begin(); 
    for (; it_B != myBs->end(); ++it_B) 
    { 
     std::vector<A*>::const_iterator it_A = it_B->getA().begin(); 
     for (; it_A != it_B->getA().end(); ++it_A) // <-- Error during execution: vector iterator incompatibles 
     { 
      // Do stuff 
      // ... 
     } 
    } 
} 

Ai-je raté quelque chose?

Merci d'avance pour vos réponses.

+0

Avez-vous une erreur d'exécution? Je viens de compiler ceci et l'ai exécuté sur Mac OS X avec gcc. – chrisaycock

+0

Alors, quelle est votre question? Vous ne nous avez pas dit quel est votre problème - difficile de répondre à cela ... –

+0

"J'ai une erreur (incompatibilité vecteur itérateur) lors de l'exécution dans mon programme C++ que je ne comprends pas" n'était pas assez clair? Vraiment ? –

Répondre

6

Votre fonction getA() renvoie un vecteur par valeur. Vous initialisez votre itérateur de boucle au début de ce vecteur, mais comme le vecteur renvoyé est temporaire, il est détruit à la fin de cette ligne.

// at the end of this line the vector returned by getA is gone, so it_A is invalid. 
std::vector<A*>::const_iterator it_A = it_B->getA().begin(); 

Par conséquent, l'itérateur n'est plus valide. Vous devriez plutôt renvoyer une référence au vecteur comme celui-ci (notez le &):

const std::vector<A*> & getA() const {return myAs;} 
+0

C'était ... plutôt évident. Merci beaucoup JoshD! –

1

vous vous rendez compte que B :: GETAS() retourne une copie de ses accords pluriannuels. Donc le vecteur que it_A recouvre est une copie différente de celle dont getA(). End() continue d'être comparée à ... I.e. la boucle for ne s'arrête jamais. (Encore pire, it_A s'étend sur un vecteur <> qui est un temporaire, donc il est détruit et toutes sortes de merdes aléatoires pourraient être écrites sur ce stockage pendant que vous prétendez l'itérer.)

1

Merci pour le complet et simple repro. Le problème ici est que vous utilisez des itérateurs de 2 vecteurs différents, c'est une vérification de débogage à l'exécution.

Vous n'aviez probablement pas l'intention de le faire, mais c'est le résultat du type de retour de getA.

vous retournez une copie du vecteur et votre probablement destiné à renvoyer une référence au vecteur, comme celui-ci:

const std::vector<A*>& getA() const {return myAs;}