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

Delphi Discussion :

Différence entre Free et Destroy


Sujet :

Delphi

  1. #1
    Membre éclairé
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 681
    Points
    681
    Par défaut Différence entre Free et Destroy
    Bonjour,

    j'ai chercher sur internet et sur le forum mais je n'ai rien trouvé. Quel est vraiment la différence entre la méthode Free et Destroy. De ce que j'ai compris Free libère la mémoire (par exemple ce qui a été aloué dynamiquement) et Detroy détruit l'objet et donc son emprunte mémoire. Est-ce vraiment cela ?
    Avez vous un bout de code à montrer pour bien faire la différence ?

    Merci d'avance.

  2. #2
    Membre régulier

    Inscrit en
    Novembre 2005
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Novembre 2005
    Messages : 97
    Points : 87
    Points
    87
    Par défaut
    je pense que:

    destroy(objet):
    si objet aloué alors libreation_mémoire
    sinon erreur;

    free(objet):
    si objet aloué alors liberation_memoire
    sinon ne fé rien;(il est déjat libéré)

  3. #3
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Non ce n'ets pas tout a fait ca
    En fait c'est seulement Destroy qui est responsable de la liberation de la memoire.
    C'est la seule fonction qui a une reele existance en soit.

    Le probleme de Destroy, c'est quelle cherche a liberer l'objet et la memoire pointee par la reference de l'objet.

    C'est a dire que ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Obj := Nil;
    Obj.Destroy;
    genere une erreur car obj pointe sur "rien".

    Pour eviter cela il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    If Obj <> Nil Then Obj.Destroy;
    Une fois qu'on a compris ca .... Ca va tout seul.
    Free fait pour toi le test "If Obj <> Nil".
    C'est a dire que Free verife avant de faire appel a destroy si la reference est bien valide.

  4. #4
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    En fait, par habitude, on utilise toujours Free, et jamais Destroy. Jusqu'à maintenant, je suis passé par trois étapes de la compréhension du "pourquoi Free" :
    1. D'abord : c'est toujours plus sûr, puisqu'on le dit ;
    2. Ensuite : en fait ça sert à rien, si on code bien, on ne devrait jamais se retrouver dans une situation où on essaye de libérer nil ;
    3. Maintenant : ben si, ça sert, et drôlement ! Lorsqu'une exception est déclenchée dans le constructeur d'un objet, le destructeur est immédiatement appelé ; et souvent, dans le destructeur, on libère des objets composés... Mais si l'exception est survenue avant la création de l'objet... Ben ça fait boum Et les boums pendant qu'une exception est traitée... C'est très dangereux Et pourtant ça ne relève pas du tout d'une mauvaise programmation.

  5. #5
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Je n'avais pas encore saisi le dernier point. Merci de m'en apprendre encore un peu plus

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Une chose importante !

    Free est une méthode normale, elle est relative au pointeur de l'objet selon un offset fixe déterminé par TObject

    Destroy est une méthode virtuelle, elles est contenu dans la table des méthodes de la classe en cours !

    C'est pour cela que le test à nil est possible dans le free, car l'appel à free c'est juste un appel du genre TMethod(Objet + $08); ... alors que le Destroy c'est TMethod(Objet.MethodAddress('Destroy'); et l'accès à la Table des méthodes provoque une violation d'accès si l'objet n'a pas été instancié !

  7. #7
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll
    C'est pour cela que le test à nil est possible dans le free, car l'appel à free c'est juste un appel du genre TMethod(Objet + $08); ... alors que le Destroy c'est TMethod(Objet.MethodAddress('Destroy'); et l'accès à la Table des méthodes provoque une violation d'accès si l'objet n'a pas été instancié !
    En fait c'est pas tout à fait ça (même si ça a l'effet que tu dis).

    Pour Free, un appel à Obj.Free est transformé en Free(Obj), et pas Free(Obj + $08).

    Pour Destroy, ce n'est pas via la table des méthodes et donc MethodAddress qu'on le récupère, mais via la VMT. Ca donne quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MethodPtr := PPointer(Integer(Obj.ClassType) + vmtDestroy)^;
    MethodPtr(Obj);
    C'est donc le Obj.ClassType qui provoque une violation d'accès si Obj = nil.

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Pour Free, un appel à Obj.Free est transformé en Free(Obj), et pas Free(Obj + $08).
    Euh, je ne parlais pas de Free(Obj + $08). mais de TMethod(Objet + $08) (c'est $04 d'ailleurs) qui désignait un cast à la volée du pointer en méthode ...

    Sinon, intéressant, c'est vrai que le Destroy est une méthode virtuelle mais pour le TObject elle est compilé en dur puisque c'est lui qui instaure la base des pointeurs objets ... c'est bien compliqué ... mais tout cela explique cette phrase de l'aide que j'ai considéré comme un dogme delphi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    N'appelez pas Destroy directement. Appelez plutôt Free. Free vérifie que la référence de l'objet n'a pas la valeur nil avant d'appeler Destroy.

  9. #9
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par ShaiLeTroll
    Euh, je ne parlais pas de Free(Obj + $08). mais de TMethod(Objet + $08) (c'est $04 d'ailleurs) qui désignait un cast à la volée du pointer en méthode ...
    Il n'empêche que c'est quand même pas ça Free étant une méthode statique, son "offset" n'est pas un offset (= déplacement), c'est l'adresse réelle de sa première instruction.
    Citation Envoyé par ShaiLeTroll
    Sinon, intéressant, c'est vrai que le Destroy est une méthode virtuelle mais pour le TObject elle est compilé en dur puisque c'est lui qui instaure la base des pointeurs objets ...
    Il n'y a strictement aucune différence entre la virtualité de Destroy ou d'une de tes méthodes. Les deux sont rangées dans la VMT, avec des offsets déterminés par le compilateur, "en dur".

  10. #10
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 435
    Points : 5 848
    Points
    5 848
    Par défaut
    salut

    tiens par curiosite je viens d'aller voir le code
    je suis un peu supris que ce soit une methode et pas une methode de class

    je m'explique,en regle generale l'acces a une methode devrais normalement si l'objet n'est pas instancié provoquer une ecxeption et dans le cas de la methode free elle ne le fait pas pourquoi ?
    a l'inverse une methode de class n'a pas besoin que l'objet soit instancié ce qui me parait ici etre fortement conseillé non ?


    @+ Phil

  11. #11
    Membre éclairé
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 681
    Points
    681
    Par défaut
    Donc si j'ai bien compris si je crée une classe de base (qui a donc pour ancêtre TObjet) mon destructeur devra être plûtot Destroy puisqu'il c'est une classe virtuelle et qu'il faut donc l'implémenter. Alors que Free est déjà implémenter donc il faudrait faire une surcharge.
    Mais j'ai lu que Free appelait Destroy si elle existait est-ce vrai ?

  12. #12
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 435
    Points : 5 848
    Points
    5 848
    Par défaut
    salut


    tu as mal compris il faut toujours utiliser free pour detruir l'objet a l'ecxeption des objet telque les tform et tframe ou la il faut utiliser release afin que les messages en court soit traiter avant la fermeture de l'instance appelante

    mais la surcharge du destructor ce fait toujours sur le destroy


    @+ Phil

  13. #13
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par anapurna
    je m'explique,en regle generale l'acces a une methode devrais normalement si l'objet n'est pas instancié provoquer une ecxeption et dans le cas de la methode free elle ne le fait pas pourquoi ?
    a l'inverse une methode de class n'a pas besoin que l'objet soit instancié ce qui me parait ici etre fortement conseillé non ?
    Non, l'appel à une méthode (statique) sur un objet non instancié ne provoque pas d'erreur.
    C'est le premier accès à un champ dans le code de la méthode qui déclenche l'exception. Or dans Free, si Self vaut nil, on ne fait rien, donc pas d'accès à un champ, donc pas d'exception.
    Si c'était une méthode de classe, ben on ne saurait rien faire, puisqu'on aurait pas de référence à l'objet qu'on veut libérer

  14. #14
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 435
    Points : 5 848
    Points
    5 848
    Par défaut
    salut

    on peut quand meme recuperer le self dans une methode de class

    @+ Phil

  15. #15
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par anapurna
    on peut quand meme recuperer le self dans une methode de class
    Oui mais ce n'est pas le même Self. Dans ce cas c'est la référence à la classe (logique, c'est une méthode de classe). C'est un peu comme si c'était :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var Self : class of TMaClass

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Citation Envoyé par sjrd
    Il n'y a strictement aucune différence entre la virtualité de Destroy ou d'une de tes méthodes. Les deux sont rangées dans la VMT, avec des offsets déterminés par le compilateur, "en dur".
    Oh, j'ai honte, j'ai encore confondu méthodes, VMT, et le RTTI pour la publication des méthodes via leur nom ...

  17. #17
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 955
    Points
    3 955
    Par défaut
    Citation Envoyé par ShaiLeTroll
    Oh, j'ai honte, j'ai encore confondu méthodes, VMT, et le RTTI pour la publication des méthodes via leur nom ...
    T'auras qu'une petite claque

    cdlt

Discussions similaires

  1. Différence entre un "bidouilleur" et un Pro ?
    Par christ_mallet dans le forum Débats sur le développement - Le Best Of
    Réponses: 290
    Dernier message: 28/11/2011, 10h53
  2. Réponses: 7
    Dernier message: 02/04/2010, 13h32
  3. Différence entre Powerpack et Free : vaut-elle la peine ?
    Par iDaaX dans le forum Mandriva / Mageia
    Réponses: 3
    Dernier message: 11/11/2007, 15h53
  4. Différences entre jmp, jz, jnz, etc
    Par christbilale dans le forum Assembleur
    Réponses: 3
    Dernier message: 05/07/2002, 15h09
  5. Réponses: 3
    Dernier message: 07/05/2002, 16h06

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