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 :

Désallocation de mémoire ...


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    460
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 460
    Points : 112
    Points
    112
    Par défaut Désallocation de mémoire ...
    Hello !

    P'tite question sur la désallocation de mémoire :


    J'ai une liste (doublement chainée, mais peu importe) dont chaque cellule contient un pointeur sur void.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct scell
    {
      void * value;
      struct scell * next, * previous;
    }
    cell;
     
     
    typedef struct slist
    {
      int nbcell;
      cell * first, * current, * last;
    }
    list;
    Ce pointeur sur void va en fait pointer sur deux structures différentes (une destinée aux competitions et l'autre aux concurrents). Je mets pour l'exemple celle des competitions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct competition
    {
      char matric[3], intitule[36], datedeb[9], pays[4];
      int tabinscp[100];
      int flagcompet;
      int poscp;
    };
    Au cours de mon programme j'ai donc alloué de la mémoire pour ces structures.
    Ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct competition * p_compet;
    p_compet = malloc( sizeof( struct competition ) );
    Et cela autant de fois qu'il y a de compétitons (idem pour les concurrents)

    J'ai également chaque fois créé une nouvelle celleule dans ma liste afin de "contenir" la structure compétition sus-créée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
        lis->current = lis->last->previous;
        lis->current->next->previous = ( cell * ) malloc( sizeof( cell ) );
        lis->current->next->previous->value = x;
        lis->current->next->previous->previous = lis->current;
        lis->current->next->previous->next = lis->current->next;
        lis->current->next = lis->current->next->previous;
        ( lis->nbcell ) ++;
      }

    Voilà !...
    Bon, maintenant, j'en suis à la libération de toutes ces structures (fin de programme). Est-ce qu'un free d'une cellule va automatiquement engendrer un free d'une structure (je ne pense pas mais je voudrais une confirmation) ?

    Merci !

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Bon, maintenant, j'en suis à la libération de toutes ces structures (fin de programme). Est-ce qu'un free d'une cellule va automatiquement engendrer un free d'une structure (je ne pense pas mais je voudrais une confirmation) ?
    Effecivement, il va falloir mettre un free pour la structure.

    Quelques remarques:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       lis->current->next->previous = ( cell * ) malloc( sizeof( cell ) );
    Un test pour vérifier que le malloc a réussi serait bien

    Ce pointeur sur void va en fait pointer sur deux structures différentes (une destinée aux competitions et l'autre aux concurrents)
    Pourquoi ne pas utiliser une union?

    Jc

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    460
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 460
    Points : 112
    Points
    112
    Par défaut
    Pourquoi ne pas utiliser une union?
    C-à-d ?

  4. #4
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    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
     
    typedef union sdata
    {
      struct competition *compet;
      struct concurrent *concur;
    }data;
     
    //Type de données
    #define AUCUN 0
    #define COMPET 1
    #define CONCUR 2
     
    typedef struct scell
    {
      data value;
      int type;
      struct scell * next, * previous;
    }
    cell;
    Avantages:
    - Le code est plus lisible et plus "gérable", on teste le type pour savoir quel est la nature
    de la cellule, il n'y a plus d'erreur possible de pointeur (confondre un pointeur competiton avec un pointeur concurrent)

    - Il n'y aura plus de pointeur void*, c'est donc mieux car ça provoque souvent des erreurs

    Inconvénients:

    - C'est un peu plus long à coder car tu as une union

    - La variable type utilise un peu plus de mémoire mais tu pourrais le mettre en short, ou si tu sais qu'il n'y a pas de confusion, tu pourrais l'enlever carrément. Bien qu'à ce moment là, le seul avantage à l'utilisation d'une union réside à ne plus avoir de pointeur void, ce qui n'est pas forcément négligeable.


    Jc

    EDITION: C'est sûrement une affaire de goût... Quoique la plupart des gens sont d'accord pour éviter les pointeurs void...

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    460
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 460
    Points : 112
    Points
    112
    Par défaut
    Euh oui, ça a l'air pas mal ... mais là je suis sur la fin de mon projet donc je vais pas tout changer

    Merci quand meme

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par fearyourself
    Quoique la plupart des gens sont d'accord pour éviter les pointeurs void...
    Quand tu fais du code générique tu n'as pas le choix.
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 89
    Points : 91
    Points
    91
    Par défaut
    on peut remplacer void * par un type par ex. liste_t dans un liste.h :
    typedef type que l'on veut liste_t;
    si on change de type il y a juste un mot à changer, l'anvantage c'est de ne pas tout recoder à chaque fois et d'éviter les casts.

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par ciol2.6.12
    on peut remplacer void * par un type par ex. liste_t dans un liste.h :
    typedef type que l'on veut liste_t;
    si on change de type il y a juste un mot à changer, l'anvantage c'est de ne pas tout recoder à chaque fois et d'éviter les casts.
    Pas de cast en C. void * est compatible avec tous les types pointeurs sur objets (et inversement).

    Le code générique est utilisé tel quel sans modification. C'est l'utilisateur qui connait ses données. (voir qsort() et sa fonction de comparaison).

    Il peut ajouter une surcouche d'interface si il veut...
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 89
    Points : 91
    Points
    91
    Par défaut
    Pas de cast en C. void * est compatible avec tous les types pointeurs sur objets (et inversement).
    ah bon.
    Pourtant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void fonction()
    {
         int m;
         void *p = &m;
         *p = 2;  /* code correct :  *(int *)p = 2; */
    }
    ne compile pas.

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Mais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void fonction()
    {
         int m;
         void *p = &m;
         int *pi = p;
         *pi = 2;
    }
    Compile parfaitement.
    et pire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void fonction()
    {
         float f;
         void *p = &f;
         int *pi = p;
         *pi = 2;
    }
    Compile aussi.
    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.

Discussions similaires

  1. Problème de désallocation de mémoire
    Par ratan dans le forum Langage
    Réponses: 7
    Dernier message: 06/12/2011, 17h20
  2. Erreur de désallocation de mémoire
    Par ZAYDOUN dans le forum OpenCV
    Réponses: 10
    Dernier message: 05/08/2008, 16h27
  3. désallocation de mémoire
    Par Tex-Twil dans le forum C
    Réponses: 12
    Dernier message: 19/10/2006, 10h09
  4. allocation/désallocation de mémoire
    Par kinta dans le forum C++
    Réponses: 2
    Dernier message: 10/02/2006, 09h52
  5. Désallocation mémoire des types record
    Par mounis dans le forum Langage
    Réponses: 2
    Dernier message: 07/02/2006, 13h21

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