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 :

[FAQ] "Que vaut un pointeur après free() ?" -> Réponse inexacte [FAQ]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut [FAQ] "Que vaut un pointeur après free() ?" -> Réponse inexacte
    Bonjour,

    La FAQ dans sa question Que vaut un pointeur après free() ?

    énonce :

    Le pointeur reste inchangé (en effet il est passé par valeur à free)
    Je pense que cette assertion est inexacte. Voici les passages de la Norme sur lesquels je m'appuie pour dire cela :

    7.20.3 Memory management functions
    1 (...) The lifetime of an allocated object extends from the allocation until the deallocation.
    6.2.4 Storage durations of objects
    1 2 An object has a storage duration that determines its lifetime. There are three storage durations: static, automatic, and allocated. Allocated storage is described in 7.20.3.
    (...)
    The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.
    Cordialement

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Le deuxième paragraphe que tu cites corrobore entièrement ce que tu lis dans la FAQ. La fonction free() sert à libérer de la mémoire allouée par malloc(). Or, cette dernière renvoie l'adresse du début de la mémoire en question. Et cette adresse, il faut la recevoir dans un pointeur. Mais ce pointeur, lui, est complètement indépendant de la mémoire allouée par malloc() et doit même exister avant.

    Ainsi, si tu libères la mémoire allouée, il n'y aucune raison que cela affecte le contenu du pointeur. À dire vrai, il n'y aucune relation entre les deux. Si tu ne vois que le pointeur, tu ne peux absolument pas affirmer, ni même savoir de façon simple si la zone qu'il pointe a été allouée avec un malloc() ou pas ...

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Le deuxième paragraphe que tu cites corrobore entièrement ce que tu lis dans la FAQ.
    Non justement.


    Citation Envoyé par Obsidian Voir le message
    Ainsi, si tu libères la mémoire allouée, il n'y aucune raison que cela affecte le contenu du pointeur.
    Tu spécules là. La Norme dit que la valeur du pointeur est complètement indéterminée dès lors que la durée de vie de l'objet est achevée, ce qui est le cas lorsque la libération de l'objet alloué antérieurement ainsi que le 2ème paragraphe l'explique. En particulier la valeur du pointeur peut avoir changé voire être une adresse invalide. C'est probablement rare dans la pratique mais on ne peut pas l'exclure.

    Je pense donc que la réponse donnée dans la FAQ est erronée. En fait, c'est assez peu gênant puisque dans la pratique, lorsqu'on a libéré, on se moque de savoir ce que vaut le pointeur qui pointait vers la zone allouée. Par contre, la 2ème partie de la réponse est correcte mais je répète c'est la question que je trouve curieuse.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La valeur du pointeur ne peut pas être changée par un appel à free() vu que le pointeur est passé par valeur. C'est impossible.

    De plus, toutes les copies dudit pointeur ne sont pas affectées non plus. Seule la zone pointée est affectée.

    Le problème, ce n'est donc pas la FAQ, c'est que la norme est mal exprimée sur ce point-là. Ce qui est certain, c'est que lorsque la fin de vie de l'objet pointé est atteinte, déréférencer le pointeur aura un comportement indéterminé.
    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 confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Il y a une subtilite: la representation reste inchangee, la valeur de cette representation devient indeterminee.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    La valeur du pointeur ne peut pas être changée par un appel à free() vu que le pointeur est passé par valeur. C'est impossible.
    OK, c'était pour me faire comprendre que j'ai parlé d'une valeur du pointeur qui aurait changé. La seule chose qui importe c'est que la valeur du pointeur devient indéterminée comme le dit très clairement pas la Norme (et c'est sur ce point que la FAQ est inexacte).


    Citation Envoyé par Médinoc Voir le message
    Le problème, ce n'est donc pas la FAQ, c'est que la norme est mal exprimée sur ce point-là.
    ou encore : Il est tombé par terre, c'est la faute à Newton !!!




    Citation Envoyé par Médinoc Voir le message
    Ce qui est certain, c'est que lorsque la fin de vie de l'objet pointé est atteinte,
    Ça oui, le Norme le dit clairement dans le même extrait (et la FAQ aussi dans la même question).

    Citation Envoyé par Médinoc Voir le message
    déréférencer le pointeur aura un comportement indéterminé.
    Bien sûr mais ça va au-delà :

    J.2 Undefined behavior
    1 (...)The value of a pointer to an object whose lifetime has ended is used (6.2.4).

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Désolé, j'ai du mal à piger la différence entre "les bits contenus dans un pointeur" et "la valeur d'un pointeur" et comment la "valeur" peut changer sans que les bits changent (et sans 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.

  8. #8
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par c-candide Voir le message
    Bonjour,
    The lifetime of an allocated object extends from the allocation until the deallocation.
    est une phrase qui concerne les objets alloués pour une durée de vie "automatic" (donc C++ uniquement…).

    Cela ne concerne donc pas les pointeurs qui sont "allocated", càd les pointeurs retournés par malloc() (et ses cousins)…) et libérés par free(). Puisque le "lifetime" de ces objets est entièrement sous le contrôle de celui qui écrit le code…



    Pour les pointeurs "automatic", la norme dit simplement que dès que l'on quitte le bloc dans lequel le pointeur est alloué, on ne peut plus compter sur la valeur même du pointeur.

    En clair cela veut dire que ceux qui écrivent les compilateurs et les optimiseurs sont libres de désalloué l'espace qui a servi au pointeur lui-même quand cela leur chante : dès la sortie du bloc… à la fin de la fonction… du moment que la mémoire (en général le stack pour les pointeurs et objets "automatic"… ) où est allloué le pointeur est libérée qu'elle que soit la manière de sortir de la fonction… (return, throw, longjmp, …)

    Donc en effet pour un pointeur sur un objet "automatic", le contenu même du pointeur peut être modifié dès que le pointeur est désalloué… mais en pratique, en C++, vous auriez une erreur de compilation (sauf contorsion avec des pointeurs de pointeurs ou autre…) à vouloir accéder directement à une variable en dehors du bloc où elle est déclarée… cette remarque de la norme est dès lors un peu redondante par rapport à la syntaxe C++…

    Mais notez que tout çela concerne les "automatic" et votre question concerne "free()" - donc les "allocated" - pour lequel tout le monde vous a répondu clairement : free() ne modifie pas la valeur de son paramètre… mais après free() l'accès au bloc alloué et référencé par le pointeur n'est plus possible sans risquer un SIGSEGV.

    Par contre vous n'en n'aurez pas systématiquement (de SIGSEGV)… c'est là que le "undetermined" de la norme intervient : ce qui se passe dépend uniquement de l'implémentation (en particulier de la librairie de gestion mémoire et de l'OS…).

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pour les pointeurs "automatic", la norme dit simplement que dès que l'on quitte le bloc dans lequel le pointeur est alloué, on ne peut plus compter sur la valeur même du pointeur.

    Peux-tu m'expliquer ce que tu appelles un pointeur "automatic" ?
    Si tu veux dire alloca(), le standard C ne connait pas de toute façon. Si tu veux dire qu'il ne faut pas retourner l'adresse d'une variable locale, dis-le simplement!
    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.

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pour les pointeurs "automatic", la norme dit simplement que dès que l'on quitte le bloc dans lequel le pointeur est alloué, on ne peut plus compter sur la valeur même du pointeur.

    Peux-tu m'expliquer ce que tu appelles un pointeur "automatic" ?
    Si tu veux dire alloca(), le standard C ne connait pas de toute façon. Si tu veux dire qu'il ne faut pas retourner l'adresse d'une variable locale, dis-le simplement!
    tout ce qui est alloué par alloc et C° sont des "allocated"… (Lapalisse en aurait dit autant…)

    les pointeurs "automatic" sont les références à des objets "automatic" : c'est donc une notion purement C++ (comme dit dans le post ci-dessus…) qui n'existe pas en C…

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La notion de mémoire "automatique" existe tout-à-fait en C, elle est seulement trop souvent oubliée.

    Et elle signifie tout simplement "dans la pile", donc les variables locales non-statiques (et à l'époque, non-registres, bien que la durée de vie soit la même).
    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.

  12. #12
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    La notion de mémoire "automatique" existe tout-à-fait en C, elle est seulement trop souvent oubliée.

    Et elle signifie tout simplement "dans la pile", donc les variables locales non-statiques (et à l'époque, non-registres, bien que la durée de vie soit la même).
    variable automatique en C oui…
    mais objet (et pointeur sur…) automatique non : çà c'est du C++…

    et restons sur le sujet : une mauvaise interprétation d'une norme en mélangeant des paragraphes qui parlent de choses bien distinctes et qui fait contester à tort les explications de la FAQ concernant la valeur d'un pointeur après free()…

  13. #13
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    Citation Envoyé par c-candide Voir le message
    Bonjour,
    The lifetime of an allocated object extends from the allocation until the deallocation.
    est une phrase qui concerne les objets alloués pour une durée de vie "automatic" (donc C++ uniquement…).
    La citation de c-candide étant issue de la norme C, je ne vois comment elle ne pourrait concerné que le C++ !

Discussions similaires

  1. Réponses: 23
    Dernier message: 13/09/2010, 13h17
  2. Que vaut le Fortran ?
    Par Extra-Nitro dans le forum Fortran
    Réponses: 20
    Dernier message: 07/02/2006, 23h05
  3. comment savoir ce que fait mon pointeur??
    Par elekis dans le forum C++
    Réponses: 9
    Dernier message: 30/11/2004, 12h42
  4. Que vaut DirectX 9 ?
    Par LKT dans le forum DirectX
    Réponses: 3
    Dernier message: 07/02/2003, 08h25

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