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 de mémoire


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Par défaut Allocation dynamique de mémoire
    Bonjour,
    Je débute en C++, et j'ai déjà un petit problème. J'explique mon cas (en espérant être clair):
    Je viens lire un fichier binaire qui contient dans une première partie des paramètres généraux (noms, date, heure, ..., et notament nombre de configuration), puis suivant le nombre de configuration, je viens lire les paramètres de(s) configuration(s). Je veux ranger tous ces paramètres dans une seule structure de la forme suivantes: Paramètres généraux + Nb_conf structure de paramètres de configuration.
    Pour l'instant mon programme marche bien car j'alloue en dur le nombre de configuration de mon fichier de test. J'aimerais utiliser les fonctions new et delete du C++, mais j'avoue ne pas bien saisir l'utilisation de ces fonctions. Pour l'instant, mon programme est de la forme suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct format_Conf
    {
      int a, b, c, d, e;
      double f, g, h;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct format_Parametre
    {
      int Nom, Nb_Conf;
      double Date, Heure;
      struct format_Conf Conf[10];  // il y a neuf configurations dans mon fichier test (1 à 9)
    };
    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
     
    int main(void)
    {
      int i;
      struct format_Parametre Parametre;
    ...
      fread(&Parametre.Nb_Conf, sizeof(int), 1, fid);                          // Nombre de configurations
     
      for(i=1;i<=Parametre.Nb_Conf;i++)
      {
    	fread(&Parametre.Conf[i].a, sizeof(int), 1, fid);	        
    	fread(&Parametre.Conf[i].b, sizeof(int), 1, fid);
                ....
      }
    }
    Voilà, si quelqu'un pouvez m'aider à y voir plus clair, ce serait cool.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut, et bienvenue sur le forum.
    Je vais oser quelques remarques préliminaires avant de te donner la réponse...
    • En C++, la déclaration d'une structure ou d'une classe provoque d'office la création du type correspondant... il est donc inutile de faire précéder la déclaration de variables du mot clé struct
    • En C++, il existe une série de classes qui facilitent la gestion de tout ce qui est la lecture et l'écriture d'informations dans des fichier. Il s'agit des classes ifstream (lecture) et ofstream(écriture), toutes les deux disponibles dans l'espace de nommage std en incluant le fichier d'entete <fstream>. Elles présentent, entre autres avantages, le fait d'avoir les opérateur >> ou << (selon le cas) qui facilitent la lecture/l'écriture des informations (reporte toi à l'entrée de la FAQ qui s'y rattache )
    • Il existe plusieurs conteneurs (vector, set, list ...) dans l'espace de nommage qui sont de nature à faciliter grandement la gestion d'éléments multiples
    • n'oublie pas le return 0; avant la dernière accolade fermante de ta fonction main
    • le C++ autorise la déclaration de variables ailleurs qu'au début des fonctions, et l'habitude à prendre est généralement de déclarer les variables quand on en a réellement besoin, et quand on sait quelle valeur leur donner (voir de déclarer des variables "super locales" dans le sens où elle n'existeront que dans la portée d'un bloc particulier)
    • A choisir, on préférera bien souvent utiliser un fichier "texte" comme fichier de configuration plutôt qu'un fichier binaire, entre autre pour éviter les problèmes de compatibilité (boutisme, voire, taille des entier)


    Maintenant, pour ce qui concerne la réponse...

    Tu peux avoir une approche "C style" du problème, et décider de travailler avec un pointeur et l'allocation dynamique personnelle de la mémoire, voire, sans utiliser la classe ifstream.

    A ce moment là, tu devras modifier ta structure format_Parametre sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct format_Parametre
    {
      int Nom, Nb_Conf;
      double Date, Heure;
      format_Conf *Conf;
    };
    qui sera alors gérée à peut près sous la forme de
    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
    int main(void)
    {
      struct format_Parametre Parametre;
    ...
      fread(&Parametre.Nb_Conf, sizeof(int), 1, fid);
      /* allocation de la mémoire pour Nb_conf parametres */
      Parametre->Conf=new format_Conf[Parametre.Nb_Conf];
      for( int i=1;i<=Parametre.Nb_Conf;i++)
      {
    	fread(&Parametre.Conf[i].a, sizeof(int), 1, fid);	        
    	fread(&Parametre.Conf[i].b, sizeof(int), 1, fid);
                ....
      }
     
      /* il ne faudra pas oublier de libérer la mémoire allouée dynamiquement
       * quand on n'aura plus besoin de Conf
       */
      delete[] Parametre->Conf;
      return 0;
    }
    Mais tu peux aussi avoir une approche "C++" du problème, dans le sens où tu décidera d'utiliser les facilités que t'offre le langage (sans, forcément, partir sur une optique Orientée Objet ) et on ne t'incitera jamais assez à préférer cette approche.

    Dans le cas présent, l'approche "C++" consisterait à
    1. utiliser la classe ifstream pour la lecture du fichier (*idéalement* de créer un fichier texte plutôt qu'un fichier binaire)
    2. utiliser, par exemple, la classe vector pour maintenir le tableau de Format_Conf


    La structure format_Parametre deviendrait alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct format_Parametre
    {
      int Nom, Nb_Conf;
      double Date, Heure;
      std::vector<format_Conf> Conf[10];
    };
    et la fonction main deviendrait
    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
    int main(void)
    {
      struct format_Parametre Parametre;
      std::ifstream ifs("nomdufichier");
      /* ou std::ifstream ifs("nomdufichier",std::ios_base::binary) si tu décide
       * de garder le fichier binaire 
       */
      ifs>>Parametre.NbConf;
     
      for(int i=1;i<=Parametre.Nb_Conf;i++)
      {
            /* on déclare une "super locale" qui permet de lire les parametres :D 
             */
    	format_conf read;
            /* on lit toutes les informations
             */
            ifs>> read.a >> read.b >> read.c >> read.d >> read.e >> read.f
               >>read.g>>read.h;
            /* et on rajoute le tout dans le tableau */
            Parametre.Conf.push_back(read);
      }
      /*...*/
      return 0;
    }
    Nota: Une fois que tu sera habitué au C++, tu pourrais aussi envisager de t'intéresser à la biliothèque boost::program_options, qui fournit tout ce qu'il faut pour gérer les faciliter la gestion d'options de programmes
    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
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Ca, c'est la vision plutôt "C" de la chose

    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
     
       // lecture du nombre de configuration
       fread(&Parametre.Nb_Conf, sizeof(int), 1, fid);
     
       // allocation du nombre de configuration
       // attention, ton membre de structure conf n'est plus 
       // struct format_Conf Conf[10];  
       // mais struct format_Conf *Conf
       Conf = malloc(Parametre.Nb_Conf * sizeof(struct format_Conf));
     
       // controle de l'allocation
       if(Conf == NULL)
       {
          // traitement d'erreur
       }
     
       // ensuite tu peux acceder a conf comme avant
       // au fait, pourquoi tu commence à 1 et pas à 0 ?
      for(i=1;i<=Parametre.Nb_Conf;i++)
      {
    	fread(&Parametre.Conf[i].a, sizeof(int), 1, fid);	        
    	fread(&Parametre.Conf[i].b, sizeof(int), 1, fid);
                ....
      }
     
       // a la fermeture, il faut liberer la memoire
       // la syntaxe est un peut barbare
       free (Conf);
    Pour la vision C++, il te faudrait créer deux classes "format_Parametre" et "format_Conf" avec les mêmes membres que tu as déjà définis.

    La classe "format_Parametre" possede en plus un membre qui est un vector de "format_Conf"

    La classe format_Conf doit avoir en plus les fonctions "constructeur de copie", "operateur d'affectation" et "serialize" (pour renseigner ses données à partir d'un flux externe)

    Et dans ce cas, tu n'a plus à t'embeter avec les "new" et "delete"
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    C'est la raison pour laquelle j'ai parlé d'une optique "C style" et non d'une optique C...

    Il est clair que, si l'on veut pousser la chansonnette à son terme, il faut conseiller l'optique OO, avec constructeur, destructeur, opérateur d'assignation et tout le saint frusquin... Mais, dans le sens où Rodinia dit lui-même qu'il débute, je ne suis pas persuadé que le matraquer avec l'orienté objet dés le départ soit la meilleure des choses à faire
    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

  5. #5
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 14
    Par défaut
    Merci pour vos réponses. Je comprend mieux l'utilisation de ces fonctions.
    Mon code à une approche 'C' car c'est le langage que j'avais vagement étudié à l'école, mais je vais me documenter sur la classe ifstream pour l'orienter un peu plus 'C++'. Pour ce qui est des fichiers de configuration binaires, ils me sont fournis dans ce format, je ne peut donc pas utiliser de fichier texte.
    Ma boucle 'for' commence à 1, pour simplifier la relecture par la suite, car dans mon cas la conf 0 n'existe pas. D'ailleurs, est-t-il possible de supprimer Conf[0] de ma stucture? M'enfin c'est pas trop important.
    Encore merci.

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

Discussions similaires

  1. probleme d'allocation dynamique de mémoire
    Par Blo0d4x3 dans le forum C
    Réponses: 2
    Dernier message: 13/03/2007, 07h53
  2. Allocation dynamique de mémoire : Limitations ?
    Par rulianf dans le forum C++
    Réponses: 5
    Dernier message: 22/03/2006, 17h03
  3. Allocation dynamique de mémoire
    Par cd090580 dans le forum Autres éditeurs
    Réponses: 7
    Dernier message: 12/11/2005, 11h17
  4. [VC++/ASM] Allocation dynamique de mémoire ?
    Par Magus (Dave) dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 21/12/2004, 15h05
  5. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31

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