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 :

destruction d'une structure


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut destruction d'une structure
    Bonjour, je reprends le code d'un ami et il y a une partie qui me "gêne". Voilà en gros son code :

    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
     
    typedef struct{
    blabla
    }A;
     
    A * CreateA(blabla)
    {
      A * a=malloc(sizeof(*a));
      blabla
      return a;
    }
     
    void DestroyA(A * a)
    {
      blabla
      free(a);
      a=0;
    }
    Je doute qu'après Destroy(a) le pointeur soit remis à NULL. J'aurais plus fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void DestroyA(A ** a)
    {
      blabla
      free(*a);
      *a=NULL;
    }
    et DestroyA(&a); car a est une recopie.
    Qu'en pensez-vous ?
    Merci.

  2. #2
    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
    En effet.
    Encore que, je serais plutôt du genre à mettre a à NULL moi-même après l'appel de la fonction (mais dans ce cas, j'aurais supprimé la ligne inutile a=0;)...
    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.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut Medinoc,
    merci de "me donner raison".
    Ceci dit, pourquoi préfères-tu mettre a à NULL après la destruction et non dans le destructeur (pour reprendre le langage C++) ?

  4. #4
    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
    Ce n'est pas un destructeur.
    Et c'est parce que j'ai l'habitude de me servir de free(), et que je préfère rester cohérent.
    De plus, ça marche avec un type de pointeur précis, mais s'il est question de n'importe quel type (genre free()), ça ne passe plus : il faut forcément un cast.
    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.

  5. #5
    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 salseropom
    Bonjour, je reprends le code d'un ami et il y a une partie qui me "gêne". <...> Je doute qu'après Destroy(a) le pointeur soit remis à NULL. J'aurais plus fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void DestroyA(A ** a)
    {
      blabla
      free(*a);
      *a=NULL;
    }
    et car a est une recopie.
    La solution que tu préconises est correcte, et je l'ai déjà vue utilisée, mais ça ne résout pas tous les problèmes. En effet il est sain de mettre le pointeur à NULL après une libération, mais ça ne va pas mettre magiquement tous les pointeurs 'alias' (les autres pointeurs sur la même zone) à NULL pour autant (ce qui tu as bien mis en évidence dans la première version de DestroyA()).

    Personnellement, je préfère donc rester explicite, et écrire clairement
    et éventuellement , si il y a des alias :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       DestroyA(a), a = NULL, data.pa = NULL;
    etc.

    Le tout avec des opérateurs ',', ce qui rend le code visuellement 'insécable', car il résiste à une indentation automatique (contrairement à ';').
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    mais ça ne va pas mettre magiquement tous les pointeurs 'alias' (les autres pointeurs sur la même zone) à NULL pour autant
    oui mais si après chaque free() il y a une remise à NULL du pointeur donc dans ce cas tous les pointeurs "alias" seront remis à NULL non (et il n'y aurait plus de problème) ? (j'ai peur d'avoir un raisonnement un peu trop naïf...)

  7. #7
    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
    Destroy() connait UN pointeur, pas tous les autres...
    Ce que Emmanuel veut dire à propos de pointeurs "alias", c'est que N pointeurs peuvent pointer sur le même objet...
    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.

  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 salseropom
    oui mais si après chaque free() il y a une remise à NULL du pointeur donc dans ce cas tous les pointeurs "alias" seront remis à NULL non (et il n'y aurait plus de problème) ? (j'ai peur d'avoir un raisonnement un peu trop naïf...)
    J'essaye justement de te faire prendre conscience du contraire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
    int main (void)
    {
       char *pa = "hello";
       char *pb = pa;
     
       pa = NULL;
     
       puts (pb);
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre actif Avatar de ronan99999
    Inscrit en
    Juillet 2003
    Messages
    279
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Juillet 2003
    Messages : 279
    Points : 299
    Points
    299
    Par défaut
    Peut-etre en redefinissant ton free.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    //p est l'adresse de ton pointeur à liberer
    #define MY_FREE(p) do{ free(*(p)),*(p) = NULL;}while(0)
     
    //exemple
     
    char *pc;
     
    *pc = (char*) malloc(sizeof(*pc)*NB_CHAR);
    //...
     
    if(pc)
     MY_FREE(&pc);
    Si tu ne te plantes pas, comment veux tu pousser?

  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
    Pas de référence en C++, et pourquoi passer par un pointeur dans une macro ?
    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.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    OK, je vois la "subtilité" des pointeurs alias.
    Merci.

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

Discussions similaires

  1. Segmentation fault sur destruction d'une structure
    Par User Name dans le forum Débuter
    Réponses: 9
    Dernier message: 30/03/2011, 15h31
  2. sizeof() d'une structure
    Par tut dans le forum MFC
    Réponses: 12
    Dernier message: 29/08/2006, 18h21
  3. Comment mettre en place une structure 3 tiers.
    Par WOLO Laurent dans le forum Débats sur le développement - Le Best Of
    Réponses: 13
    Dernier message: 27/07/2003, 22h01
  4. [toFAQ][socket] Envoi d'une structure
    Par julien20vt dans le forum C++
    Réponses: 15
    Dernier message: 23/04/2003, 15h47
  5. longueur d'une structure
    Par bohemianvirtual dans le forum C
    Réponses: 6
    Dernier message: 28/05/2002, 18h31

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