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 :

allocation dynamique et sauvegarde sur fichier


Sujet :

C++

  1. #1
    Membre averti Avatar de elmcherqui
    Profil pro
    Inscrit en
    Février 2008
    Messages
    281
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Maroc

    Informations forums :
    Inscription : Février 2008
    Messages : 281
    Points : 382
    Points
    382
    Par défaut allocation dynamique et sauvegarde sur fichier
    bonsoir ,
    j'ai une structure qui contient un tableau double dimension que j'alloue dynamiquement puis je sauvegarde le tous en binaire , ensuite j'essaie de creer une seconde structure puis je recupere les donne depuis les fichier et j'affiche .

    mon bout de code est tres tres simple donc la lecture sera rapide :
    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
    61
    62
    63
    64
    65
    #include<iostream>
    #include<fstream>
    using namespace std;
     
     
    struct map {
    	char** terrain; // [20][30]
    	void remplir();
    	void sauvegarder();
    	void charger();
    	void afficher();
    };
     
    void map::remplir(){
     
    	terrain = new char* [20];
    	for(int i=0;i<20;i++)
    		terrain[i] = new char [30];
     
    	char remplissage='a';
    	for(int i=0;i<20;i++){
    		for(int j=0;j<30;j++)
    			terrain[i][j] = remplissage;
    			remplissage++;
    	}
    }
     
    void map::afficher(){
    	for(int i=0;i<20;i++){
    		for(int j=0;j<30;j++)
    			cout<<terrain[i][j];
    		cout<<endl;
    	}
    }
    void map::sauvegarder(){
    	ofstream file("modele",ios::out | ios::binary );
    	file.write((char*)this,sizeof(map));
    	file.close();
    }
    void map::charger(){
    	ifstream file("modele",ios::in | ios::binary );
    	if(!file )
    	{
    		cout<<"fichier introuvable"<<endl;
    		return;
    	}
    	file.read((char*)this,sizeof(map));
    	file.close();
    }
     
    int main()
    {	//quand je met cette partie en commentaire sa ne marche pas
    	map ancien;
    	ancien.remplir();
    	ancien.sauvegarder();
     
     
    	map nouv;
    	nouv.charger();
    	nouv.afficher();
     
     
    	cout<<endl;
    	return 0;
    }
    pourquoi quand j'enleve la premiere partie du main sa ne marche pas ?
    merci de m'aider .

  2. #2
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Aïe
    Je pense qu'il faut déplacer cette question vers le sous-forum débuter. D'une manière générale, il ne faut pas utiliser de pointeurs "nus" (le membre terrain de votre classe) en C++, surtout si on débute, mais au contraire les structures de la bibliothèque standard, qui se chargent de toute la tuyauterie à votre place.
    Par ailleurs, la persistance sur des structures dynamiques (ce que vous essayez de faire avec vos fonctions membre sauvegarder et charger) est un problème qui n'est même pas géré par cette librairie standard. Certes, des librairies existent (boost, eternity, etc.), mais elles ne sont pas très faciles à utiliser pour un débutant.

    Ce que vous souhaitez faire est tout à fait légitime, et est très simple à faire en Java ou autre langage plus accessible, mais nécessite une connaissance plus approfondie du C++ que ce qui transparait de votre code.

    Pour répondre plus précisément à votre question: ce n'est pas le fait de mettre en commentaire ou non la première partie de votre code qui le fait marcher ou non. Vous utilisez un pointeur nu dans votre classe, qui est donc indéfini à la création d'un objet; toute lecture sur un objet avant l'appel de remplir sera donc aléatoire, ce qui est un bug gravissime même si votre code ne l'expose pas en l'occurrence. Par ailleurs, d'une exécution à l'autre, non seulement toute mémoire dynamique allouée lors d'une exécution précédente est perdue, mais les adresses mémoire elles-mêmes (c'est à dire les valeurs numériques de ces pointeurs nus) sont différentes, donc lors d'une lecture sur fichier d'une adresse mémoire en provenance d'une session d'exécution précédente, on est pratiquement sûr de générer le même genre d'erreur: un pointeur vers une zone invalide. Enfin, remarquez que vos procédures de sauvegarde et de chargement ne sauvent ni ne chargent les données qui vous importent, à savoir le contenu du terrain.

  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,
    [Remarque]:Je trouve un peu délicat le nom 'map' pour ta structure. Il existe un std::map qui n'a pas du tout le même sens.[/Remarque]

    Essaies ce code tu devrais comprendre ton erreur :
    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
    #include <iostream>
    #include <typeinfo>
     
    struct A
    {
       char *pc;
    };
     
    struct B
    {
       char pc[10];
    };
     
    struct C
    {
       char *pc;
       virtual ~C(){}
    };
     
    template<class T>
    void dump()
    {
       std::cout<<typeid(T).name()<<" : "<<std::endl;
       T t;
       std::cout<<" sizeof(pc) = "<<sizeof(t.pc)<<std::endl;
       std::cout<<" &t = "<<&t<<std::endl;
       std::cout<<" &(t.pc) = "<<&(t.pc)<<std::endl;
    }
    int main()
    {
       dump<A>();
       dump<B>();
       dump<C>();
       return 0;
    }

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Ce qu'il faut comprendre ici est le concept de sérialisation: On ne peut pas sauvegarder un pointeur dans un fichier, il faut donc tout mettre dans un format pouvant tenir dans un simple tableau/flux d'octets.

    À cela s'ajoutent les problèmes de compatibilité, qui disent que le format de sérialisation doit être indépendant du système: Si tu sauvegardes un entier 32 bits "comme sur le système", un fichier créé sur une machine little endian (comme un PC) ne pourra pas être lu sur une machine big endian (comme certains serveurs sous *n*x).

  5. #5
    Membre averti Avatar de elmcherqui
    Profil pro
    Inscrit en
    Février 2008
    Messages
    281
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Maroc

    Informations forums :
    Inscription : Février 2008
    Messages : 281
    Points : 382
    Points
    382
    Par défaut
    merci pour les reponses , je vois plus clair maintenant , par contre 3Darchi je ne vois vraiment pas ou tu veux en venir avec ton bout de code , merci de m'expliquer s'il te plait .

  6. #6
    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
    C'est un peu ce que t'a dit Médinoc :
    Un pointeur n'est pas la zone qu'il pointe : sizeof(A)!=sizeof(B)
    Une classe (une structure est une classe) est plus que ses membres : sizeof(A)!=sizeof(C)
    Il n'y a pas de lien entre l'adresse d'un objet et l'adresse de son premier membre : &c != &(c.pc)

    -> Il en découle ce que te dit Médinoc: ta sérialisation devrait plus ressembler à ton 'afficher', c'est à dire à l'écriture de tes membres explicitement en prenant en compte les problèmes éventuels de multiplateforme. Tu peux serialiser les données imbriquées (tes tableaux par exemple) à l'intérieur de la sérialisation de ton objet ou utiliser un mécanisme de référencement.

    Si tu dois mettre en oeuvre la sérialisation dans le cadre d'un projet pro alors intéresses-toi à Boost :
    -> Boost.Serialization : La sérialisation avec Boost, par Pierre Schwartz
    -> Boost.Serialization : Utilisation de Boost.Serialization pour sérialiser des classes MFC, par Farscape
    -> Ou au mécanisme de sérialisation de ton framework (MFC/Qt/wxWidgets) s'il en possède un.

  7. #7
    Membre averti Avatar de elmcherqui
    Profil pro
    Inscrit en
    Février 2008
    Messages
    281
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Maroc

    Informations forums :
    Inscription : Février 2008
    Messages : 281
    Points : 382
    Points
    382
    Par défaut
    Merci pour les informations

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

Discussions similaires

  1. Sauvegarde sur fichier PDF
    Par Carrel dans le forum Excel
    Réponses: 1
    Dernier message: 24/06/2008, 17h26
  2. sauvegarder un fichier Access sur un réseau
    Par ginger dans le forum Access
    Réponses: 9
    Dernier message: 08/11/2004, 15h20
  3. Question sur les problèmes d'allocation dynamique
    Par slylafone dans le forum C++
    Réponses: 23
    Dernier message: 25/10/2004, 14h18
  4. Réponses: 2
    Dernier message: 14/05/2004, 12h55

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