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 :

Écriture et lecture dans un fichier ouvert en mode binaire


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Par défaut Écriture et lecture dans un fichier ouvert en mode binaire
    Je teste un peu le C++, et j'obtiens à la compilation :

    *** Error in `/home/jessie/workspace/c++-002/Debug/c++-002': double free or corruption (fasttop): 0x00000000023f9260 ***

    Je cherche et je n'ai pas encore le recul pour comprendre l'erreur.

    Voici les sources si quelqu'un peut m'aider à comprendre ce serait sympa.
    Je suis sous GNU Debian Linux et j'utilise Eclipse et le compilateur GCC.

    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
    #include <iostream>
    #include <cmath>
    #include <fstream>
     
    #include "Adresse.h"
     
    using namespace std;
     
     
     
    int main()
    {
    	char file[26] = "Essai";
     
    	ofstream monFlux(file, ios::binary);
    	if(monFlux)
    	{
     
    	}
    	else
    	{
    	cout << "Erreur" << endl;
    	}
     
     
    Adresse Personne1(102, "Charles", 1990, 26);
    Adresse Personne2(100, "Inconnu", 1900, 0);
     
    monFlux.write((char *) &Personne1, sizeof Personne1);
    monFlux.close();
     
    	ifstream lire(file, ios::binary);
     
     
    	lire.read((char *) &Personne2, sizeof Personne2);
    	if(lire)
    		{
     
    		}
    		else
    		{
    		cout << "Erreur" << endl;
    		}
     
     
    Personne1.Lecture_Attribut();
    Personne2.Lecture_Attribut();
     
    lire.close();
     
     
    }
    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
    #ifndef ADRESSE_H_
    #define ADRESSE_H_
     
    #include <iostream>
    #include <string>
     
    class Adresse
    {
     
    public:
     
    	// Constructeur par defaut
    	Adresse();
     
    	// Constructeur
    	Adresse(	signed int vi_cle,
    				std::string string_nom,
    				signed short vs_annee,
    				signed short vs_age	);
     
     
    	void Lecture_Attribut();
     
    	~Adresse();
     
    private :
     
    	signed int mvi_cle;
    	std::string mstring_nom;
    	signed short mvs_annee;
    	signed short mvs_age;
     
     
    };
    #endif /* ADRESSE_H_ */
    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
    #include "Adresse.h"
     
    // Constructeur par defaut
    Adresse::Adresse()
    {
    	mvi_cle = 0;
    	mstring_nom = "Inconnu",
    	mvs_annee = 0,
    	mvs_age = 0;
    }
     
    // Constructeur
    Adresse::Adresse(	signed int vi_cle, std::string string_nom, signed short vs_annee, signed short vs_age ) :
    										mvi_cle(vi_cle),
    										mstring_nom(string_nom),
    										mvs_annee(vs_annee),
    										mvs_age(vs_age)
    {
     
    }
     
    // Destructeur par Defaut
    Adresse::~Adresse()
    {
    	// TODO Auto-generated destructor stub
    }
     
    // Methode Lecture Attribut
    void Adresse::Lecture_Attribut()
    {
    	std::cout << mvi_cle << "\n";
    }

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Cette erreur survient en général quand on libère la mémoire pointée (par un pointeur non null) mais déjà libérée.

    L'une des façons les plus courante d'y parvenir, c'est de copier un pointeur dans un constructeur par copie (par exemple, généré par le compilateur), et qu'on détruit le pointé dans le destructeur.

    Dans le code que tu montres, je ne le vois pas.
    Utilise un débuggeur, pour trouver dans quel destructeur ce produit l'erreur.

  3. #3
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Adresse Personne2(100, "Inconnu", 1900, 0);
     
    monFlux.write((char *) &Personne1, sizeof Personne1);
    monFlux.close();
     
    	ifstream lire(file, ios::binary);
     
     
    	lire.read((char *) &Personne2, sizeof Personne2);
    Cette partie du code me semble douteuse. La fonction membre read requiert un char *, il faut lui fournir un vrai char *. Caster un pointeur objet en char * ne converti pas l'objet, juste le pointeur. Ton problème vient de ce que la fonction read, de par cette conversion "douteuse" considère la zone mémoire de l'objet de type adresse comme une suite de caractère. Il écrase donc les données spécifique de Personne2 avec des char. Et quand l'objet est détruit, les membres qui contiennent des données incohérentes vont accéder à des zones mémoires interdites.

    La bonne pratique consiste à créer un buffer (ici un tableau de char) que tu passes à la fonction lire puis transférer ce buffer à ton objet par la fonction qui va bien (qui dans ton cas n'existe pas encore, tu dois donc la rajouter à ta classe Adresse). Tu peux aussi utiliser une fonction qui utilise un std::string à la place d'un buffer (cf ::getline) que tu passeras à ton objet. Avec cette deuxième méthode tu n'as pas à te préoccuper de la taille des données reçues, string se charge de tout.


    Bonne chance.

  4. #4
    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
    Je doute que tu obtiennes ça à la compilation, c'est une erreur à l'éxécution.
    Tes read et write avec cast en char* sont bien cavaliers et devraient être modifiés avant toute chose.
    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.

  5. #5
    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
    Wow. On dirait du C, où l'on pouvait se permettre de lire et écrire des structures complètes directement dans un fichier binaire... à condition de savoir ce que l'on faisait.

    En C++, cette approche ne passe pas avec les classes modernes. Il faut faire soi-même la sérialisation des données, et C++ préfère fortement les fichiers texte aux fichiers binaires.
    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.

  6. #6
    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
    N'allons pas aussi loin, les fichiers binaires sont tout autant utiles et utilisés en C++.
    Ton programme affiche ce que tu attends avant de planter ? Que Personne1 et Personne2 ont les mêmes infos ?
    A priori, l'erreur vient à la destruction de Personne2.
    Avec ton mauvais write, ce que tu écris dans le fichier ne correspond pas à grand chose, surtout pour le nom(? je suppose, on ne sait absolument rien de ton Adresse). A vue de nez tu chopes au mieux le pointeur vers la string interne. Quand tu read, tu donnes ce pointeur à Personne2, et quand chacun le détruit, ça crash.
    C'est dommage d'utiliser des fstream pour en faire un truc aussi moche. Pour utiliser fstream et (dé)sérialiser une classe, on surcharge les opérateur >> et <<.
    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.

  7. #7
    Membre éclairé
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Par défaut
    Effectivement c'est à l'execution et non à la compilation ce message d'erreur.

    Oui c'est façon C que j'ai voulu copier des blocs d'un coup.

    Je travail le C++ mais je sature. Le livre de de jesse liberty le langage C++ et pas tres fournis sur le travail avec les fichiers.
    Son exemple et fourni tel quel je l'ai moi meme ecris.

    J'ai besoin de comprendre, je mis prend mal pour l'instant.
    Oui j'ai ce que je veux, personne2 contient bien personne1.

    Le debugger m'amene bien sur string.

    Merçi pour ses explications rapides.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lecture et écriture de données dans un fichier
    Par follichon dans le forum C
    Réponses: 1
    Dernier message: 24/11/2011, 12h17
  2. Problème lecture écriture par bloc dans un fichier
    Par scary dans le forum Débuter
    Réponses: 5
    Dernier message: 22/04/2009, 19h28
  3. [POI] Problème écriture/lecture dans un fichier Excel
    Par steuve dans le forum Documents
    Réponses: 6
    Dernier message: 02/07/2007, 15h47
  4. écriture/lecture dans des fichiers
    Par rafale001 dans le forum C
    Réponses: 14
    Dernier message: 02/03/2007, 16h59
  5. Réponses: 12
    Dernier message: 14/06/2004, 13h06

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