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

Langage C++ Discussion :

Lecture de fichier binaire et "double free or corruption"


Sujet :

Langage C++

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 64
    Points : 43
    Points
    43
    Par défaut Lecture de fichier binaire et "double free or corruption"
    Bonjour,

    Je souhaite sauvegarder un gros ensemble de donnée sous la forme d'un fichier binaire
    pour ne pas perdre de temps à la lecture, et afin que cela ne prenne pas trop de place.

    Avant de me lancer dans l'écriture du code correspondant dans mon programme j'ai
    décidé de me faire un petit test "local". Ce test échoue lamentablement sans que je puisse comprendre pourquoi .....

    Je n'ai aucun problème à l'écriture du fichier binaire, mais à la lecture de celui-ci les choses se compliquent, en effet l'utilisation de in.read(..) me provoque un "double free or corruption", erreure bien connue des développeurs utilisant GCC.

    Voici mon code (lisez bien les quelques commentaire):
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <string.h>
     
    using namespace std;
     
    typedef struct voxel 
    {
                    vector<int> values;     
                    float posx;
                    float posy;
                    float posz;
     
    }voxel_t;
     
    int main(void) 
    { 
            voxel_t vo;
     
            vo.posx=0.2;
            vo.posy=0.6;
            vo.posz=0.8;
     
            //si décommenté : double free or corruption
            //vo.values.push_back(1);
     
            /*
            vo.truc.push_back(1);
            vo.truc.push_back(1);
            vo.truc.push_back(1);
            vo.truc.push_back(1);
            vo.truc.push_back(1);
            */
     
            ofstream out("test.bin", ios::out | ios::binary);
            out.write((char*)&vo, sizeof(vo));
            out.close();
     
            voxel_t vr;
            ifstream in("test.bin", ios::in | ios::binary);
            //decommanter cette ligne "supprime le double free or corruption" :
            //mais retourne mauvaises valeurs
            //in.seekg(sizeof(vr));
            in.read((char*)&vr, sizeof(vr));
            in.close();
     
            cout << "posx : " << vr.posx <<endl;
            cout << "posy : " << vr.posy <<endl;
            cout << "posz : " << vr.posz <<endl;
            /*
            for(int i = 0 ; i < vr.truc.size() ; i++)
            {
                    cout << "truc value : " << vr.truc[i] <<endl;
            }
            */
     
            return 0;
    }
    Lorsque je ne n'utilise pas le membre vector<int> je n'ai plus le double free or corruption ... Savez-vous d'où pourrait venir ce problème ?

    Merci,

    Cordialement,

    Azmodai,

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Quand tu fais , tu récupères que la taille de ta structure et pas celle de ton vecteur. Quelque soit la taille du vecteur, la valeur est la même. De plus, en utilisant , qui te dit que les données de vo sont contigue en mémoire ?

    Le mieux est de donner les opérateurs << et >> pour ta classe
    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
    ostream& operator<< (ostream& out, const volex& v)
    {
       out << v.posx << v.posy << v.posz << v.values.size();
       for (vector<int>::const_iterator it = v.values.begin(); it != v.values.end(); ++it)
          out << *it;
       return out;
    }
     
    istream& operator>> (istream& in, volex& v)
    {
       vector<int>::size_type size = 0;
       int value = 0;
       in>> v.posx >> v.posy >> v.posz >> size ;
       for ( ; size  != 0; --size )
       {
          in>> value;
          v.values.push_back(value);
       }
       return in;
    }

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,

    Juste parce que j'aime bien les algorithmes et les itérateurs, je me permet de légèrement modifier les opérateurs << proposés par gbdivers :
    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
    #include <iterator>
    #include <algorithm>
    ostream& operator<< (ostream& out, const voxel& v)
    {
       out << v.posx << v.posy << v.posz << v.values.size();
       std::copy(v.values.begin(),v.values.end(),std::ostream_iterator<int>(out,""));
       return out;
    }
     
    istream& operator>> (istream& in, voxel& v)
    {
       vector<int>::size_type size = 0;
       in>> v.posx >> v.posy >> v.posz >> size ;
       v.values.reserve(size);
       std::copy(
        std::istream_iterator<int>(in)
        ,std::istream_iterator<int>()
        ,std::back_inserter(v.values)
        );
     
       return in;
    }
    Cela étant dit, cette forme de sérialisation à la main est très fragile. Alors pourquoi ne pas utiliser une bibliothèque éprouvée qui sait très bien le faire . Par exemple, Boost.Serialisation : La sérialisation avec Boost, par Pierre Schwartz

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    +1 3DArchi

    J'utilise habituellement ce code avec Qt et QDataStream, ce qui permet une vraie sérialisation, contrairement à fstream. Même si on travaille sur une seule plateforme, c'est une bonne habitude à prendre de sérialiser.

    Pour l'utilisation des algorithmes, aucune excuse de ma part. Je vais aller copier 500 fois "je dois penser à utiliser les algorithmes de la STL"

Discussions similaires

  1. Réponses: 6
    Dernier message: 08/11/2012, 09h17
  2. Lecture de fichier binaire et gestion de fin de fichier
    Par habasque dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 02/05/2007, 17h06
  3. lecture ecriture fichier binaire
    Par jonckers dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/04/2007, 09h12
  4. Réponses: 5
    Dernier message: 26/03/2007, 01h30
  5. lecture de fichier binaire
    Par Salim6 dans le forum C
    Réponses: 3
    Dernier message: 07/11/2005, 19h56

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