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 :

double free or corruption (fasttop) sur un vecteur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Par défaut double free or corruption (fasttop) sur un vecteur
    Bonjour,

    J'ai rencontré cette fameuse erreur en manipulant un vecteur dans mon code... et là chose étonnante c'est que je n'ai pas manipulé explicitement la mémoire avec un free ou avec un destructeur etc... d'une manière incorrecte, et pourtant ce sont les principales causes pour cette erreur si j'ai bien suivi.

    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
    vector<CDart> fonction(CDart* d){
        vector<CDart> vect;   
        CDart* dartCourante = d;
        vect.push_back(*dartCourante);
       do{
            vect.push_back(*dartCourante);
            dartCourante = dartCourante->next();
        }while(isEqual(dartCourante->next(), d->next() == false); 
     
        vect.push_back(*d);
     
        return vect;
    }
    L'objectif ici est de stocker tous les objets de type CDart dans un vecteur en utilisant la fonction next de la classe CDart. (Dans la pratique ces objets sont liés entre eux par une liste chainée). A la fin je réajoute l'élément de début (ça m'est utile par la suite, car j'y ajouterai plusieurs listes chainées consécutives et la répétition de cet élément me servira de point de repère dans mon vecteur).

    Après des tests pour voir ce qui pose problème, je m'aperçois que c'est l'ultime ajout dans le vecteur qui est en défaut... mais pas systématiquement.

    Je ne vois vraiment pas en quoi j'ai tripatouillé la mémoire de manière incorrecte... quelqu'un peut m'aider ?

    Merci d'avance !

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Ne serait-ce pas un problème au niveau de l'opérateur d'affectation de CDart ?

    J'ai l'impression que tu place deux fois le premier élément dans ton std::vector.

    Peux-tu nous montrer comment est construite cette classe ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Par défaut
    Bonjour,
    Oui je place effectivement mon élément 2 fois dedans.
    Si on raisonne par exemple sur les entiers de 1 à 5 (plutot que des CDarts), je vais avoir quelque chose comme ceci :
    fonction(1) = <1, 2, 3, 4, 5, 1>
    L'objet passé en paramètre à ma fonction va engendrer une série qui finit obligatoirement par boucler. Je m'arête quand j'ai repéré cette boucle, et je rajoute une dernière fois le dernier élément à la fin. Pourquoi ? parce que par la suite je vais "coller" à la fin de ce vecteur le résultat de la fonction appliqué à un autre élément et ile me servira (entre autre) de séparateur entre ces chaînes.
    Au final j'aurais par exemple : <1, 2, 3, 4, 5, 1, 6, 7, 8, 6, 9, 10, 11, 9...>
    ce qui signifierai que j'ai une boucle ici qui va de 1 à 5, une autre de 6 à 8, une autre de 9 à 11 etc.
    Ce formatage des données n'est pas de mon fait, mais il a sa raison d'être et je ne peux pas le modifier (sauf si VRAIMENT c'est capital).

    Je ne peux pas linker le code de la classe CDart ici (il est réellement ENORME),
    Mais en résumé il s'agit d'un objet qui modélise une sorte d'arête orientée faisant parties de chaines, avec des fonctions qui pointent vers son successeurs, son antécédent, et d'autres CDarts bien particulières.

    Je me posais la question : peut être ai-je mal manipulé mes pointeurs ? (mais bon je ne vois pas où !).

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Peux-tu au moins poster l'opérateur d'affectation de CDart ?

    Il y a fort à parier que le problème de double free vienne de là (ou de l'opérateur d'affectation des attribut de CDart).

    Sinon, as-tu essayé d'utiliser un débogueur pour voir précisément à quelle ligne le problème de double free survenait ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 31
    Par défaut
    J''ai localisé l'erreur en faisant des affichages systématiques dans ma console pour savoir un peu ce qu'il se passe.

    Tout ce qui se trouve avant le code suivant s'execute parfaitement

    En revanche il plante systématiquement à ce moment là. Je n'ai eu aucun warning ni aucune erreur à la compilation m'avertissant que je faisais quelque chose de risqué.

    Voici les parties "clef" de la classe CDart.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //L'attribut qui donne les liens entre les CDart (en fait un tableau de pointeurs vers des CDarts)
    Private:
    CDart* FBeta[3];
     
    public:
    //Getter et setter d'un des "liens" (le 'next' de de mon premier post)
    CDart* CDart::getBeta1() const
    { return FBeta[1]; }
     
    void CDart::setBeta1(CDart* ADart)
    { FBeta[1] = ADart; }
    Ce code n'est pas de moi, et a priori il fonctionne dans l'appliation de base que je cherche à étendre. Je n'ai pas le droit de le modifier (d'autant qu'il impacte sur d'autres modules auquels je n'ai pas accès).

    Ci-dessous le code que j'ai simplifié plus haut, mais en version "non épurée" si je puis dire, afin d'éviter les erreurs de simplification de ma part et de mieux coller aux définitions/implémentations données dans ce message :
    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
     
    vector<CDart> engendrerBiface(CDart* d){
        vector<CDart> biface;   
        CDart* dartCourante = d;
        biface.push_back(*dartCourante); //Ajout du premier élément
     
        //Première série de CDart correspondant à une involution
        do{
            biface.push_back(*dartCourante);
            dartCourante = dartCourante->getBeta1();
        }while(isEqual(dartCourante->getBeta1(), d->getBeta1()) == false); 
     
        //Répétition de la dart engendrant la biface (repère et séparateur entre les 2 faces la composant)
        biface.push_back(*d);
        dartCourante = d->getBeta2(); //On change de lien entre les CDarts juste pour cette fois afin d'accéder a une autre "chaine"
     
        //Deuxième série de CDart (méthode identique à la première)
        do{
            biface.push_back(*dartCourante);
            dartCourante = dartCourante->getBeta1();
        }while(isEqual(dartCourante->getBeta1(), d->getBeta2()) == false); 
     
        return biface;
    }

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Un débogueur te donnera l'endroit exact du problème, ainsi il sera plus facile à identifier, sans compter qu'on pourra voir la valeur de certains variable et/ou exécuter pas à pas pour mieux comprendre ce qu'il se passe.

    Là, on sait juste que l'erreur survient lors de l'ajout d'un élément dans le std::vector mais on ne sait pas si le problème vient d'un constructeur par copie (si oui, le quel ? Celui de l'objet, celui d'un attribut de l'objet, d'un attribut d'un attribut de l'objet ) ou s'il vient de std::vector qui aurait été mis dans un état incohérent par on-ne-sait-quelle-action.

    Cela peut aussi être une erreur dans le constructeur de CDart, bref, il faudrait plus de détail sur la localisation de l'erreur.

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    je ne vois aucune raison valable de vouloir faire un vector de copie puisque tu as des pointeurs...
    Ton vector est retourné par copie, et qui dit copie dit que l'original est supprimé
    Le nombre de copies réalisées dans ce code est assez grandiose, et de toute évidence tes CDart ne sont pas prévus pour être copiés
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Comme le dit Neckara tu devrais plutôt envisager un vecteur de pointeurs. Ainsi que l'a fait remarquer Bousk, tu manipules à la base des pointerus, autant rester homogène.

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/05/2019, 17h27
  2. double free or corruption (fasttop) sur un vecteur
    Par fred94190 dans le forum C++/CLI
    Réponses: 2
    Dernier message: 21/06/2013, 13h40
  3. [SFML] Image double free or corruption
    Par Belegkarnil dans le forum SFML
    Réponses: 4
    Dernier message: 23/08/2007, 16h56
  4. erreur glibc detected double free or corruption.
    Par Screwt-K dans le forum C++
    Réponses: 1
    Dernier message: 02/07/2007, 16h46
  5. Problème d'éxécution: double free or corruption
    Par ciol_tebroc dans le forum C++
    Réponses: 3
    Dernier message: 17/05/2006, 19h44

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