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 :

Question simple Free / Variable


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Par défaut Question simple Free / Variable
    Hello,
    j'ai trouvé ceci dans un programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    PROCEDURE TToto.FreeObject( Item : TObject );
    Begin
      Item.Free;
      Item := Nil; // Cela ne sert à rien de mettre à NIL car "Item" n'est pas un paramètre par variable
    End;
    Vous aurez remarqué le commentaire sur le ":= Nil".

    Ma question en suivant : d'accord, mais alors dans ce cas là, le free sert il à quelque chose ?

    Je suppose qu'il ne fait que libérer l'espace mémoire alloué localement à Item, mais pas l'espace mémoire de la variable manipulée par l'appelant de la procédure... Mais j'attends les avis des experts.

    Merci.

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 940
    Billets dans le blog
    6
    Par défaut
    Les objets sont passés par adresse [EDIT=mea culpa]=> c'est équivalent à un var Item: TObject;

    mais il existe depuis Delphi 5 au moins une procedure FreeAndNil qui fait déjà ça et (je crois) ne lève pas d'exception si l'argument n'est pas assigné.

    [EDIT] l'intérêt de mettre Nil, c'est de ne pas faire planter si on cherche à utiliser cet Item déjà libéré à condition de tester si bien assigné : if Assigned(Item) then Item.Execute;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 950
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 950
    Par défaut
    Citation Envoyé par peter27x Voir le message
    Ma question en suivant : d'accord, mais alors dans ce cas là, le free sert il à quelque chose ?
    Bien sûr puisque le paramètre pointe bien sur un objet existant

    Citation Envoyé par tourlourou Voir le message
    Les objets sont passés par adresse => c'est équivalent à un var Item: TObject;
    Pas tout à fait ! Item (sans var ni const) est une copie du pointeur locale à la fonction. Affecter nil à Item n'affectera donc que sa copie.

    Citation Envoyé par tourlourou Voir le message
    mais il existe depuis Delphi 5 au moins une procedure FreeAndNil qui fait déjà ça et (je crois) ne lève pas d'exception si l'argument n'est pas assigné.
    Free commence par faire un test sur Self <> nil avant d'appeler Destroy pour s'assurer de l'assignation du pointeur. C'est pour cela qu'il est conseillé d'appeler Free plutôt que Destroy directement. FreeAndNil cumule simplement l'appel à Free et l'assignation de nil au pointeur (passé en var ici)

  4. #4
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Par défaut
    OK merci à vous.
    Donc avec var, ce n'est pas une copie du pointeur mais le pointeur lui même qui est passé, et le nil aurait alors son intérêt. Sans var c'est une copie, mais comme elle pointe sur la même adresse mémoire que l'original, le free va aller libérer cette adresse là, donc on est bon.
    Pour le freeandnil en effet c'est un programme assez ancien, ça devait pas exister à l'époque de son écriture.
    Désolé, mais après plus de deux ans sans pratiquer, j'ai un peu perdu certaines bases.

  5. #5
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Par défaut
    Quand même une remarque : en C, par exemple, un paramètre passé par adresse ou bien par valeur, c'est pas exactement comme en Delphi, c'est ça ? Le passage de paramètre Delphi est un peu particulier, non ?

  6. #6
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Par défaut
    J'ai trouvé ceci dans un tuto Delphi du site (celui de Didier Mailliet) :

    C. Paramètre donnée variable

    1. définition

    Il s’agit d’un passage de paramètres par valeur. On ne précède le nom du paramètre d’aucun mot (ni var, ni const ni out).
    Le paramètre peut avoir une valeur avant l’appel, sa valeur peut être modifiée dans la procédure, la modification n’est pas
    transmise au retour.

    2. exemple


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure essai (x,y : byte);
    begin
    y := x // y prend la valeur de x
    end;
    Var
    a,b : byte:
    ...
    a:= 3; b:= 2;
    essai (a,b); // a et b conservent leurs valeurs
    Ma question : si l'affectation d'une valeur à y ne s'applique pas à b, alors pourquoi, si j'ai bien compris les explications de Andnotor, le fait de faire y.free s'appliquerait à b ?

    Merci.

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 115
    Par défaut
    ne confond pas un type simple comme Byte et un objet !

    Si l'on repart sur ta méthode FreeObject

    FreeObject appelle la méthode Free, cela invoque du code DE l'objet, il manipule directement SA mémoire
    C'est le Free qui travaille sur l'objet !

    FreeObject effectue une affectation d'une nouvelle valeur mais tout le code est DANS FreeObject et cela ne modifie pas l'objet mais la référence local Item sur celui-ci !

    Pense à Self, sur Free ou toute méthode d'objet, il y a un paramètre invisible qui est l'objet lui-même, si l'on traduisait Free objet en un Free procédural :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TObject.Free;
    begin
      if Self <> nil then
        Destroy;
    end;
    deviendrait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure Free(Obj: TObject);
    begin
      if Obj <> nil then
        Destroy(Obj);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 950
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 950
    Par défaut
    y.free ne s'applique pas à b, mais à la donnée pointée par b. Nuance

    Modifie ton essai ainsi pour t'en convaincre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure Essai(x, y :PByte);
    begin
      y^ := x^; //La valeur pointée est modifiée
      y  := x;  //Le pointeur ne l'est pas
    end;
     
    essai(@a ,@b);
    En sortie, b vaudra a.

  9. #9
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Par défaut
    Je pense que je me suis mal fait comprendre.

    Pour faire simple voici ce code simplifié :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    PROCEDURE FreeObject( Item : TObject );
    Begin
      Item.Free;
    end;
     
    var
      b : TObject;
     
    begin
      FreeObject(b);
      // est il équivalent à
      b.Free;
      // ?
    end;
    Ce que je cherche à savoir, c'est si depuis l'appelant, la variable b ici de type TObject passée par valeur (sémantiquement c'est ça) est affectée par le Free exécuté dans la procédure ou pas.

    Car pour moi, si item est une copie de b (ce qui me semble logique) alors le item.free doit s'appliquer à item (la variable locale à la procédure), mais pas à la variable b de l'appelant.

    Désolé si je vous embête avec tout ça...

    Si ça vous embête pas alors coooool

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

Discussions similaires

  1. question simple sur une variable date
    Par xavier_dcf dans le forum Débuter
    Réponses: 2
    Dernier message: 14/02/2013, 15h53
  2. Question simple sur les variables
    Par roxydu33 dans le forum Débuter
    Réponses: 3
    Dernier message: 14/04/2010, 21h00
  3. Question simple : Double dollar d'une variable PHP
    Par foxbond dans le forum Langage
    Réponses: 7
    Dernier message: 04/10/2009, 22h24
  4. Simple question sur les variables
    Par terry90 dans le forum Langage
    Réponses: 6
    Dernier message: 26/06/2009, 15h59
  5. Variable sans propriétés - question simple
    Par tavarlindar dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/05/2008, 18h48

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