IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

list<> et iterator


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 180
    Par défaut list<> et iterator
    Bonsoir,

    Je fais un projet scolaire sur les maillages, et j'ai un problème avec l'utilisation de iterator dans les listes.
    Je vais essayer d'être le plus clair possible : en gros j'ai 2 classes principales, une classe Point et une classe Triangle.
    Je voudrais stocker dans une liste mes triangles, et faire ensuite différents opérations sur ces triangles ( donc avoir accès au éléments de ma liste).

    J'ai en particulier une fonction "arete" qui me retourne, à partir d'un triangle, 2 autres triangles, que voici ( avec quelques calculs d'erreurs intermédiaires) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    vector<Triangle> arete( const Triangle & T,  const FormuleInteg & fi, double(*f)(const Point &, const Triangle &  )){
    	vector<Triangle> triangles(6);
     	triangles[0] = Triangle(T.A ,(T.A+T.B)/2. ,T.C);
    	triangles[1] = Triangle( (T.A+T.B)/2. ,T.B ,T.C);
    	triangles[2] = Triangle(T.A,T.B,(T.C+T.B)/2.);
    	triangles[3] = Triangle((T.C+T.B)/2.,T.C,T.A);
    	triangles[4] = Triangle(T.B,T.C,(T.A+T.C)/2.);
    	triangles[5] = Triangle(T.B,(T.A+T.C)/2.,T.A);
    	int indicedumin ;
    	double ermin =10.,er ;
     
    	for (int i=0;i<6;++i){
    		er = erreur(T,fi,f);
    		if(er<=ermin){
    			 ermin = er ;
    			 indicedumin = i ;
    		}
    	}
    	vector<Triangle> sortie(2);
    	if (indicedumin%2==0)
    	{
    	sortie[0]=triangles[indicedumin];
    	sortie[1]=triangles[indicedumin+1];		
    	}
    	else
    	{
    	sortie[0]=triangles[indicedumin];
    	sortie[1]=triangles[indicedumin-1];		
    	}
     
    	return sortie;
    }//sortie
    Dans le main j'ai le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int main (int argc, char *[]){
     
        const double EPS = 1 ;
        FormuleInteg fi("6points.txt");  
        Point A(0,0), B(1,0), C(0,1), D(1,1);
        Triangle T1(A,B,C), T2(B,D,C);
     
        list<Triangle> listeb,listem;
        list<Triangle>::iterator iterm;
        Triangle to;
        vector<Triangle> v(2) ;
        iterm = listem.begin();//increment des elements de liste
        listem.push_front(T1);
        listem.push_front(T2);
        v = arete(T1,fi,f);
     
     
     
             		//v = arete(to,fi,f);
     
     
     
    system("pause");
        return 0;
     
    }
    J'ai donc défini 2 triangle T1 et T2, puis 2 listes listem et listeb.
    Ce qui nous intéresse plus particulièrement pour l'instant c'est listem.

    J'ai crée un itérateur pour cette liste via la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     list<Triangle>::iterator iterm;
     iterm = listem.begin();//increment des elements de liste
    Et j'ai mis dans cette list "listem" mes 2 triangles T1 et T2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        listem.push_front(T1);
        listem.push_front(T2);
    Je voudrais maintenant accéder aux éléments de ma listes, c'est à dire à mes triangles T1 et T2. J'ai donc défini un triangle to, que j'initialise par :

    Ainsi, si je ne me trompe pas, il va en fait avoir accès au triangle T1( le premier élément de ma liste ).
    Seulement lorsque j'appelle la fonction :
    J'ai un segmentation fault....

    Mais ce que je ne comprends pas c'est que j'ai aucun souci lorsque j'appelle :
    Or j'ai to=T1 si je ne me trompe pas.

    Savez-vous quelle peut-etre la raison de cette erreur ?
    Est-ce que j'ai fait une erreur avec le *iterm ?

    Merci beaucoup, en espérant que ça soit assez clair....

  2. #2
    screetch
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        iterm = listem.begin();//increment des elements de liste
        listem.push_front(T1);
        listem.push_front(T2);
    ici tu prends l'iterateur sur le debut de la liste alors que tu n'as rien donné. selon toi, sur quoi "pointe" cet iterateur ?

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    De plus, je ne suis pas certain qu'un itérateur soit toujours valide après que la liste ait été modifiée...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    De plus, je ne suis pas certain qu'un itérateur soit toujours valide après que la liste ait été modifiée...
    Les iterateurs de listes (et de map, set) ne sont pas invalides par les editions de la liste. Mais un iterateur de fin (et celui retourne par begin() pour une liste vide en est un) continue a marquer la fin.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 180
    Par défaut
    Jean-Marc.Bourguet, sauriez-vous pourquoi je ne peux pas faire iterm++ ?
    (Je l'ai mis en commentaire à la fin de la boucle while de mon message précédent.)
    En fait il y a certains éléments de ma liste que je vais supprimer, mais j'aimerais bien à chaque fois ne pas avoir à réinitialiser l'iterateur mais plutot pouvoir enlever mes éléments tant que l'iterateur point sur un élément.
    Mais je n'arrive pas à trouver une méthode "propre"...

    EDIT : iterm++ ne rime à rien dans mon programme vu que je peux très bien en une étape avoir un nombre d'élements de ma liste inchangé...

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    J'ai oublié, il y a quand même une opération qui invalide un itérateur: l'effacement de l'élément pointé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    listem.erase(iterm);
    ++iterm;
    à remplacer par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iterm = listem.erase(iterm);
    Mais vu que tu reprends à chaque fois le premier élément...

    Au fait, j'utiliserais une deque plutôt qu'une liste pour ce genre de choses, l.empty() plutôt que l.size() != 0 (en général et surtout pour les listes, size() a une complexité en N sur les listes!), l.front() plutôt que *l.begin() et l.pop_front() plutôt que l.erase(l.begin()).

  7. #7
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Salut, tu déclares un itérateur sur une donnée qui n'existe pas...
    Déclare le après avoir fait tes push_front()...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    int main (int argc, char *[]){
     
        const double EPS = 1 ;
        FormuleInteg fi("6points.txt");  
        Point A(0,0), B(1,0), C(0,1), D(1,1);
        Triangle T1(A,B,C), T2(B,D,C);
     
        list<Triangle> listeb,listem;
        list<Triangle>::iterator iterm;
        Triangle to;
        vector<Triangle> v(2) ;
        listem.push_front(T1);
        listem.push_front(T2);
        iterm = listem.begin();//increment des elements de liste
        v = arete(T1,fi,f);
     
     
     
             		//v = arete(to,fi,f);
     
     
     
    system("pause");
        return 0;
     
    }
    D'ailleurs, tu ne préferais pas des push_back() ?

    EDIT : Grilled

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 180
    Par défaut
    D'accord, merci beaucoup à vous, c'était tout bete.

    Pour l'histoire de la modification de la liste, je vais voir ça.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 180
    Par défaut
    Comme le pressentait Medinoc, l'iterateur ne semble plus valide après modification de liste.
    Je dois donc réinitiliser à chaque fois mon iterateur, mais je trouve pas ça super... Y-a-t-il un autre moyen ?

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /* Boucle de "tri" des triangles */
           	while(listem.size()!=0){                            
                iterm = listem.begin();//increment des elements de liste
          		to = *iterm ;                 
          		v = arete(to,fi,f);
          		e1 = erreur(v[0],fi,f);
          		//cout<<"e1 "<<e1<<endl;
          		e2 = erreur(v[1],fi,f);
          		//cout<<"e2 "<<e2<<endl;
          		if(e1<EPS) listeb.push_back(v[0]);
          		else listem.push_back(v[0]);
          		if(e2<EPS) listeb.push_back(v[1]);
          		else listem.push_back(v[1]);
          		listem.erase(iterm);        
            		//iterm++;	non !!                 	
           	} //fin while

Discussions similaires

  1. Réponses: 9
    Dernier message: 29/01/2008, 12h33
  2. Itération sur une liste d'éléments
    Par anitshka dans le forum Prolog
    Réponses: 3
    Dernier message: 05/07/2006, 22h49
  3. iterator de list i+=2
    Par vincent0 dans le forum C++
    Réponses: 2
    Dernier message: 24/06/2006, 12h33
  4. [dev-C++]std::list<tree_node<T>*> iterator;
    Par jmv dans le forum Dev-C++
    Réponses: 7
    Dernier message: 06/05/2005, 13h14
  5. [struts][iterate]liste passée en parametre
    Par viena dans le forum Struts 1
    Réponses: 12
    Dernier message: 07/01/2005, 17h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo