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

C++ Discussion :

insertion d'�lements dans un vector


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    64
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 64
    Par d�faut insertion d'�lements dans un vector
    Bonjour,

    Je souhaite ins�rer des �lements apr�s un iterateur "k" (dans mon code ci-dessous)
    cependant lorsque j'exc�cute mon programme cela segfault.

    J'ai une map (pour l'exemple) : map<truc *, vector<truc *> > test;
    quand un des �lements de chacun des "vectors" contient chose_un
    le code est sens� ins�rer plusieur valeurs.

    voici le code de test :

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    class truc
    {
            public :
     
            int a;
            int b;
    };
     
    using namespace std;
     
    int main(void)
    {
            truc *chose_un = new truc();
            truc *chose_deux = new truc();
            truc *chose_trois = new truc();
     
            map<truc *, vector<truc *> > test;
     
            test[chose_un].push_back(chose_un);
            test[chose_un].push_back(chose_trois);
     
            test[chose_deux].push_back(chose_un);
            test[chose_deux].push_back(chose_deux);
            test[chose_deux].push_back(chose_un);
     
            test[chose_trois].push_back(chose_trois);
            test[chose_trois].push_back(chose_trois);
     
            std::cout << "chose_un : " << chose_un << std::endl;
            std::cout << "chose_deux : " << chose_deux << std::endl;
            std::cout << "chose_trois : " << chose_trois << std::endl;
     
            for(map<truc *, vector<truc *> >::iterator it = test.begin() ; it != test.end() ; it ++)
            {
                    for(vector<truc *>::iterator k = it->second.begin() ; k != it->second.end() ; k++)
                    {
                            if(*k == chose_un)
                            {
                                    test[chose_un].insert(k, test[chose_deux].begin(), test[chose_deux].end());
                            }
                    }
            }
     
    return 0;
     
    }
    Voici ce que j'obtiens en sortie dans mon gdb :
    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
     
    Program received signal SIGSEGV, Segmentation fault.
    __memmove_ia32 () at ../sysdeps/i386/i686/multiarch/../memmove.S:111
    111	../sysdeps/i386/i686/multiarch/../memmove.S: No such file or directory.
    	in ../sysdeps/i386/i686/multiarch/../memmove.S
    (gdb) b
    Breakpoint 1 at 0x2dd91d: file ../sysdeps/i386/i686/multiarch/../memmove.S, line 111.
    (gdb) back 
    #0  __memmove_ia32 () at ../sysdeps/i386/i686/multiarch/../memmove.S:111
    #1  0x0804b3de in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<truc*> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_algobase.h:378
    #2  0x0804b2af in std::__copy_move_a<false, truc**, truc**> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_algobase.h:397
    #3  0x0804b4db in std::__copy_move_a2<false, truc**, truc**> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_algobase.h:436
    #4  0x0804b3aa in std::copy<truc**, truc**> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_algobase.h:468
    #5  0x0804b275 in std::__uninitialized_copy<true>::uninitialized_copy<truc**, truc**> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_uninitialized.h:93
    #6  0x0804b03d in std::uninitialized_copy<truc**, truc**> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_uninitialized.h:117
    #7  0x0804ad0f in std::__uninitialized_copy_a<truc**, truc**, truc*> (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110) at /usr/include/c++/4.4/bits/stl_uninitialized.h:257
    #8  0x0804a24d in std::__uninitialized_move_a<truc**, truc**, std::allocator<truc*> > (__first=0x804f0f8, __last=0x804f0b8, __result=0x804f110, __alloc=...)
        at /usr/include/c++/4.4/bits/stl_uninitialized.h:267
    #9  0x0804a50a in std::vector<truc*, std::allocator<truc*> >::_M_range_insert<__gnu_cxx::__normal_iterator<truc**, std::vector<truc*, std::allocator<truc*> > > > (this=0x804f04c, __position=..., __first=..., 
        __last=...) at /usr/include/c++/4.4/bits/vector.tcc:525
    #10 0x08049a70 in std::vector<truc*, std::allocator<truc*> >::_M_insert_dispatch<__gnu_cxx::__normal_iterator<truc**, std::vector<truc*, std::allocator<truc*> > > > (this=0x804f04c, __pos=..., __first=..., 
        __last=...) at /usr/include/c++/4.4/bits/stl_vector.h:1102
    #11 0x0804951c in std::vector<truc*, std::allocator<truc*> >::insert<__gnu_cxx::__normal_iterator<truc**, std::vector<truc*, std::allocator<truc*> > > > (this=0x804f04c, __position=..., __first=..., 
        __last=...) at /usr/include/c++/4.4/bits/stl_vector.h:874
    #12 0x08048e57 in main () at ./main.cpp:43
    (gdb)
    cela me semble tr�s louche ...


    Ai-je manqu� quelque chose dans mon code ?
    Pouvez-vous m'�clairer ?

    merci,

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    D�tails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par d�faut
    Bonjour,

    L'insertion dans un vector invalide tous les it�rateurs pointant sur ce vector. (Car lorsqu'un vecteur atteint sa capacit�, il alloue un nouveau bloc de m�moire de taille ~2x sup�rieur � l'ancien, copie tous les �l�ments de l'ancien bloc au nouveau, puis d�truit l'ancien)

    Donc d�s le premier tour de la boucle for, l'insert dans le vector invalide l'it�rateur k.

    Il est quand m�me possible de mettre � jour un vecteur dans une boucle for, mais il faut �tre tr�s prudent et se baser sur les indices - qui sont stables - plut�t que sur les it�rateurs.

    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
     
    std::vector<truc*>& v2 = test[chose_deux];
     
    for(map<truc *, vector<truc *> >::iterator it = test.begin() ; it != test.end() ; it++)
    {
       std::vector<truc*>& v = it->second;
       for(vector<truc *>::iterator k = v.begin() ; k != v.end() ; k++)
       {
          if(*k == chose_un)
          {
             int position_it = k - v.begin();
             int range_size = v2.end() - v2.begin();
             int offset = position_it + range_size;
     
             v.insert(k, v2.begin(), v2.end());
             k = v.begin() + offset;
          }
       }
    }
    C'est tout de suite un peu plus complexe, d'ailleurs je ne suis pas certain � 100% d'avoir correctement calcul� l'offset, il y a peut �tre un +1 ou -1 � glisser quelque part

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    64
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 64
    Par d�faut
    Merci beaucoup pour la r�ponse !
    en effet je n'avais pas vu venir le probl�me ...

    ps: merci pour le bout de code !

  4. #4
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    Ceci dit, je me demande bien pourquoi:
    1. utiliser un pointeur comme cl� de ta map
    2. utiliser un pointeur comme �l�ment de ton tableau
    3. utiliser le m�me type pour repr�senter chaque tableau de ta map et la cl� qui le repr�sente
    Truc ne serait-il pas, par hasard, une chaine "C style" (tableau de caract�res termin�s par un '\0')

    Si oui, tu devrais r�ellement r�fl�chir � manipuler plut�t des std:: (w)string, car la comparaison de chaines "C stye" au moment o� tu effectue une recherche dans ta map se fera... selon l'adresse vers laquelle pointe le pointeur et non sur la valeur de la chaine (la n�cessit� d'utiliser strcmp en C pour comparer deux chaines de caract�res )

    De m�me, il n'y a que peu de raison pour manipuler des collections de pointeurs, de mani�re g�n�rale.

    Ce devrait �tre r�serv� � la manipulation d'objet polymorphes et, en tout �tat de cause, un objet polymorphe se marie tr�s mal avec la s�mantique de valeur qui est n�cessaire pour les cl�s d'une map

    Maintenant, je pars peut-�tre sur des bases bien fausses, et c'est donc � toi de voir
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

Discussions similaires

  1. R�ponses: 4
    Dernier message: 20/04/2011, 16h50
  2. Insertion de String dans un objet Vector
    Par Nazgul59 dans le forum Langage
    R�ponses: 3
    Dernier message: 08/10/2009, 16h55
  3. R�ponses: 1
    Dernier message: 25/09/2009, 09h25
  4. Soucis d'insertions dans un vector<>
    Par BigWill dans le forum SL & STL
    R�ponses: 6
    Dernier message: 14/09/2007, 15h34
  5. Fr�quence d'insertion de valeurs dans un Vector
    Par pat-trix dans le forum Collection et Stream
    R�ponses: 7
    Dernier message: 20/11/2006, 17h20

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