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 :

Plantage sur deletion de std::vector


Sujet :

C++

  1. #1
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut Plantage sur deletion de std::vector
    Bonjour,

    Ca fait plsuieurs heures que je galére là dessus sans succés. Alors quelquechose m'échape surement, je vais essayé de vous expliquer, mais le code etre trop complexe pour etre simplifé.

    J'ai une class "Data" contenant des double, float.. et une variable vector "V"
    Je crée un tableau dynamique (100 valeurs) avec new de la class "Data". J'initiale le contenu des double et je mets aussi quelques valeur dans V. Je ne rempli par nécessairement toutes "V" des 100 "Data"
    A la fin je detruit mon tableau et j'ai un plantage au destructeur de la class "Data" au titre que je fait (vue avec valgrind) un delete interdit sur la class vector.

    Je sais pas facile de comprendre avec du blabla, mais si quelquechose vous saute au yeux, je suis preneur

    Merci

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Pourrais tu nous présenter un code minimal compilable (structure + fonctions) qui reproduise le problème, que nous puissions nous faire une idée

    Merci d'avance
    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

  3. #3
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    voila a quoi ca ressemble

    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
     
    class Data
    {
      double a,b;
      float c;
      std::vector V;
      public:
      Data() {
        a=ab=0;
        c=0;
        V.clear();
      }
    };
     
    void set_data(std::vector &v)
    {
       for (int i=0;i<=9;i++) {
         ab=i;
       }
       v.append(10)
       v.append(10)
       v.append(10)
    }
     
    void main()
    {
       Data *d=new Data[100];
       set_data(d);
     
       delete[] d;
      // plantage au moment du delete
       set_data(d);
     
    }

  4. #4
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    "un code minimal compilable qui reproduise le problème"

    Le code ci-dessus est très loin de compiler. Il ne fait pas assez sens pour qu'on puisse deviner l'origine réelle du problème.

  5. #5
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Désolé, je reconnais que c'était vraiment n'importe quoi.

    voici le code épuré qui compile cette fois et qui, à mon grand désespoir, snif...ne plante pas comme dans mon code originale, sur les delete.

    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
     
    class Data
    {
      public:
      double a,b;
      float c;
      std::vector<double> V;
      Data() {
        a=b=0;
        c=0;
        V.clear();
      }
    };
     
    void set_data(Data *d);
     
    void set_data(Data *d)
    {
       for (int i=0;i<=9;i++) {
         d->a=d->b=i;
       }
       d->V.push_back(10);
       d->V.push_back(12);
       d->V.push_back(14);
       return;
    }
     
     
    int main(int argc, char *argv[])
    {
       Data *d=new Data[100];
       set_data(d);
     
       delete[] d;
       set_data(d);
     
       delete[] d;
       set_data(d);
     
       delete[] d;
       set_data(d);
      return(0);
    }

  6. #6
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Par contre je me rends compte que j'ai oublié d'y inclure un opérateur vraiment suspect. Il ne fait pas planter mais il y quelque chose de malsain dedans, mais je ne sais pas comment le réécrire proprement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      void Data::operator=(const Data &d0) {
        Data *d=this; 
        memcpy(d0,&d,sizeof(Data));
      }

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    C'est effectivement très malsain.

    C'est un comportement indéfini. Qui en pratique va conduire à des doubles suppressions de mémoire. A virer au plus vite.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Edit :
    Oula en effet avant toute chose il faut déjà supprimer au plus vite cet opérateur d'affectation complètement foireux . Surtout que si la classe Data ne contient effectivement que quelques double, float et std::vector l'opérateur d'affectation généré par le compilateur est suffisant.
    [Fin Edit]

    Ok merci, c'est plus clair.

    Le dernier code ne plante pas mais c'est un coup de chance. L'utilisation d'un tableau après qu'il est était détruit (après un appel à delete[]) est un comportement indéterminé. Cela peut crasher immédiatement comme cela peut donne l'impression de marcher (jusqu'au jour ou quelqu’un change une option de compilation ou modifie ou peu le code et boum ça plante à nouveau).

    D'ailleurs, je ne sais pas quel est ton compilateur, mais chez moi en debug, le débuggeur s'arrête à la ligne set_data(d) juste après le premier delete[] avec le message suivant :
    Windows has triggered a breakpoint in TestCpp.exe.

    This may be due to a corruption of the heap, which indicates a bug in TestCpp.exe or any of the DLLs it has loaded.
    Le reste du code ne présente pas de problème.

    Si c'est possible remplacer dans l'appli originale Data *d=new Data[100]; par std::vector<Data> d(100); et faire les modif qui vont avec devrait très probablement corriger le problème.

  9. #9
    Membre averti Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Points : 444
    Points
    444
    Par défaut
    Ok, merci pour ces corrections qui s'imposaient visiblement. Je vais mettre tout ca en oeuvre.

Discussions similaires

  1. Lenteur de gdb sur libération de std::vector
    Par Benoit_T dans le forum MinGW
    Réponses: 1
    Dernier message: 10/08/2012, 12h13
  2. delete et std::vector
    Par adurandet dans le forum C++
    Réponses: 9
    Dernier message: 31/10/2007, 17h44
  3. tri sur std::vector<std::pair<int, float> >
    Par b4u dans le forum SL & STL
    Réponses: 15
    Dernier message: 01/10/2006, 10h19
  4. 3 précisions sur l'utilisation des "std::vector"
    Par Invité dans le forum SL & STL
    Réponses: 9
    Dernier message: 10/01/2006, 01h42
  5. std::sort() sur std::vector()
    Par tut dans le forum SL & STL
    Réponses: 20
    Dernier message: 05/01/2005, 20h15

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