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 :

Libération mémoire; différents pointeurs


Sujet :

C

  1. #1
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut Libération mémoire; différents pointeurs
    Bonjour,

    J'aimerais savoir si la libération de mémoire avec un pointeur autre que celui qui a été utilisé pour l'allocation peut poser des problèmes?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdlib.h>
    int main(){
     
        int * a;
        int * b;
     
        a = malloc(size(int));
        b = a;
     
        free(b);
    }
    Est-ce que la mémoire est correctement libérée de cette manière ?

  2. #2
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Oui, la mémoire sera correctement libérée, puisque c'est le même pointeur....

  3. #3
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut
    La même adresse tu veux dire...

    Ce qui signifie que seul l'adresse de la mémoire est suffisant pour l'OS pour retrouver la zone réservée. Et donc que la taille de cette zone a été mémoriser par l'OS au moment de l'allocation.

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    oui

    par contre pas propre du tout...

  5. #5
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut
    par contre pas propre du tout...
    pourquoi pas ?

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    entraine une illisibilité, c'est dangereux, c'est tout..

    Si on alloue une varaible, pourquoi ne pas la libérer ELLE ?

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Dans tous les cas, il est recommandé d'affecter la valeur NULL à b et à a après la libération, ce qui explicite le fait qu'ils contiennent une adresse invalide.

    Thierry

  8. #8
    Membre averti Avatar de icer
    Inscrit en
    Janvier 2006
    Messages
    332
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 332
    Points : 363
    Points
    363
    Par défaut
    Si on alloue une varaible, pourquoi ne pas la libérer ELLE ?
    On pourrais, par exemple, avoir besoin d'une fonction qui se charge d'allouer une zone mémoire et de retourner un pointeur sur cette zone.

    Dans ce cas on n'a pas accès au pointeur qui servit à l'allocation, puisqu'il est caché dans la fonction.

  9. #9
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Si on alloue une varaible, pourquoi ne pas la libérer ELLE ?
    Bin comme l'a démontré icer, si tu fait une allocation d'un objet par le biais d'un constructeur, tu retournes l'adresse de l'objet, tu n'as donc plus accés au pointeur d'origine, l'essentiel est donc d'avoir l'adresse qui elle ne change pas d'un pointeur à un autre lorsqu'il s'agit du même objet.

  10. #10
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par icer Voir le message
    Dans ce cas on n'a pas accès au pointeur qui servit à l'allocation, puisqu'il est caché dans la fonction.
    Il n'est pas cache, il n'existe plus lorsque la fonction retourne. Il ne faut pas confondre une variable et sa valeur. malloc() retourne l'adresse du debut du bloc alloue, et on stocke cette adresse dans une variable speciale concue pour stocker des adresses. Cette variable speciale s'appelle un pointeur.
    Evidemment, on peut copier cette adresse et la stocker dans d'autres pointeurs. Si plusieurs pointeurs existent en meme temps avec une meme valeur (une adresse donc, si tu as suivi), et si cette valeur devient invalide (par exemple si le bloc alloue est libere), alors tous ces pointeurs deviennent inutilisables.

  11. #11
    Membre averti Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Points : 390
    Points
    390
    Par défaut
    Je pense depuis longtemps qu'un chapitre sur l'allocation mémoire devrait écrire en gras et très tôt "La valeur [ = valeur numérique] renvoyée par malloc() est la seule clé permettant d'accéder à la mémoire allouée, et de la libérer".

    Ce qui est fait dans le programme et dans l'OS dépend de l'OS, qui peut aller jusquà proposer directement les fonctions du C. Mais peu importe. Il suffit de savoir, ou plutôt d'imaginer que "tout passe comme si", que le pointeur renvoyé est un vrai pointeur pour l'accès mémoire, et une clé dans une table permettant d'accéder à un objet descripteur.

    Vous avez tout à fait raison de souligner que quand vous écrivez une fonction qui retourne un pointeur qui doit être libéré par l'appelant, vous avez une copie de la valeur retournée par malloc() dans une variable locale de la fonction, puis une copie de cette valeur dans une variable de l'appelant - sans parler de la virtuelle "variable invisible de transport", un registre par exemple.

    Vous pouvez également avoir plusieurs copies de cette valeur, par exemple une pour l'utilisation, et une autre dans un tableau contenant les [valeurs des] pointeurs à libérer.

  12. #12
    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 Pierre Maurette Voir le message
    Je pense depuis longtemps qu'un chapitre sur l'allocation mémoire devrait écrire en gras et très tôt "La valeur [ = valeur numérique] renvoyée par malloc() est la seule clé permettant d'accéder à la mémoire allouée, et de la libérer".
    Oui, et je crois que pour en terminer définitivement avec les erreurs, cette valeur doit être nommée correctement, c'est à dire 'adresse' et non 'pointeur' comme on le voit trop souvent, à commencer par cette discussion qui fait allègrement la confusion entre les deux, entretenant les erreurs de compréhension et la question originale elle même.

    Enfin, on ne 'libère pas de pointeur'. On libère le bloc mémoire dont l'adresse est contenue dans tel ou tel pointeur...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       T *p = malloc();
       T *q = p; /* aliasing */
       <...>
     
       free (q);
    est dont tout à fait valide. Bien sûr, l'aliasing est peu recommandé, mais il est techniquement possible. Le bon sens élémentaire recommande que tous les pointeurs concernés soient remis à NULL après libération du bloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        p = NULL;
        q = NULL;
    Une technique d'aliasing propre consiste à 'refiler le bébé' :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       T *q = p; /* aliasing */
        p = NULL;
    Evidemment, du code comme ceci n'existe probablement pas dans la vraie vie, par contre ceci, oui :
    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
     
    {
       MSG *m = msg_create("Hello world");
       int try = 0;
     
       int err;
       do
       {
          err  = xmit (m); /* Libère m quand l'émission réelle est terminée.
                                   Ca pourrait être dans une autre tâche... */
          if (!err)
          {
             m = NULL;
          }
          else
          {
             try++;
          }
       }
       while (err && count < 3);
     
       if (err)
       {
          msg_delete (m);
          m=NULL;
          puts("fatal error");
       }
    }

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/09/2011, 11h48
  2. Réponses: 15
    Dernier message: 10/06/2008, 15h20
  3. [COM] Libération mémoire
    Par MC2 dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 13/01/2006, 16h15
  4. Réponses: 9
    Dernier message: 19/12/2005, 16h41
  5. FIREBIRD + APPLI EN C : Problèmes de libération mémoire
    Par lio33 dans le forum Connexion aux bases de données
    Réponses: 4
    Dernier message: 16/09/2005, 09h07

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