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

Langage Delphi Discussion :

Libération de TStringList créée dans une fonction


Sujet :

Langage Delphi

  1. #1
    T-B
    T-B est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 69
    Points : 58
    Points
    58
    Par défaut Libération de TStringList créée dans une fonction
    bonjour,

    j'ai une fonction qui retourne un tstringlist que je voudrait récuperer dans un combo.

    j'ai essayé ça mais pas bon

    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      combobox1.Items.AddStrings(liste);
    end;
     
     
    function TForm1.liste : TstringList;
    Var
     l : TstringList;
    begin
     
     l :=  TstringList.create ;
     
      l.Add('a');
      l.Add('b');
      l.Add('c');
     
      Result := l;
     
     l.free;
    end;
    Merci

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 299
    Points
    11 299
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function TForm1.liste : TstringList;
    begin
      Result :=  TstringList.create ;   
      Result.Add('a');
      Result.Add('b');
      Result.Add('c');
    end;
    ou
    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
    function TForm1.liste : TstringList;
    Var
     l : TstringList;
    begin
     
     l :=  TstringList.create ;
     
      l.Add('a');
      l.Add('b');
      l.Add('c');
     
      Result := l;
     
    //  l.free; // autant ne pas le détruire avant de le transmettre !
    end;
    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
    T-B
    T-B est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 69
    Points : 58
    Points
    58
    Par défaut
    Merci

    ma fonction function liste : TstringList est dans une autre unité, je detruit quand ma liste ?

    Merci

  4. #4
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Points : 4 384
    Points
    4 384
    Par défaut

    en principe tu détruis ta liste après son utilisation en dehors de la fonction.

  5. #5
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    SAlut
    Citation Envoyé par evarisnea
    en principe tu détruis ta liste après son utilisation en dehors de la fonction.
    Etant donné que L (stringlist) a ete declaré dans une procedure, comme la detruire apres l'appel a cette procedure ?

    Il peut etre interessant de le savoir car je ne me suis jamais soucié de ca.

    A++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  6. #6
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Citation Envoyé par Qwazerty Voir le message
    Etant donné que L (stringlist) a ete declaré dans une procedure
    Probablement lié à une erreur de frappe, style code improvisé dans l'éditeur de post.
    Tu crois pas ?
    --
    jp
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  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
    Cela ne pose aucun problème particulier. Sa référence est renvoyée dans la valeur de retour, donc il suffit de récupérer cette référence, et de faire un Free dessus plus tard
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      List: TStringList;
    begin
      List := liste;
      try
        ComboBox.Items.AddStrings(List);
      finally
        List.Free;
      end;
    end;
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  8. #8
    Inactif
    Inscrit en
    Avril 2007
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 55
    Points : 53
    Points
    53
    Par défaut
    Si tu veux qu'une foncion de renvoi en stringliste il faut quelle est une existance en dehors de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function TForm1.liste : TstringList;
    Var
     l : TstringList;
    begin
     l :=  TstringList.create ;
      l.Add('a');
      l.Add('b');
      l.Add('c');
      Result := l;
     l.free;
    end;
    Non seulement cette fonction ne fait pas ce que tu veux mais il y a de fort chance qu'elle provoque une violation de mémoire quand tu utilisera le résultat

    Pourquoi?
    Quand tu arrives dans ta fonction Delphi prends l'espace memoire de la liste dans sa zone des valeurs locales, éventuellement la pile il faudrait verifier.
    Quand tu fais result:=i il empile l'adresse de la liste
    En quittant la fonction Delphi rend la place occupée par les variables locales
    Donc l'adresse qu'il a empilé pointe alors sur une zone désallouée


    Pour que ton code soit bon il faut que la TsringList soit declarée precedement à l'appel
    voici une des solutions possibles
    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    Var
     MesChoix : TstringList;
    begin
     MesChoix :=  TstringList.create ;
     combobox1.Items.AddStrings(liste(MesChoix));
     MesChoix.free
    end;
     
    function TForm1.liste(Var I: TlisteString) : TlisteString;
    begin
      l.Add('a');
      l.Add('b');
      l.Add('c');
    Result:=i
    end;
    Je n'ai pas tester mais a une faute de frappe pres cela doit etre bon

    à sjrd
    Tu as essayé mon move? Cela donne quel résultat?

    PapyJohn

  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 PapyJohn Voir le message
    Pourquoi?
    Quand tu arrives dans ta fonction Delphi prends l'espace memoire de la liste dans sa zone des valeurs locales, éventuellement la pile il faudrait verifier.
    Quand tu fais result:=i il empile l'adresse de la liste
    En quittant la fonction Delphi rend la place occupée par les variables locales
    Donc l'adresse qu'il a empilé pointe alors sur une zone désallouée
    Sauf que t'as oublié un détail : la string list est allouée sur le tas, donc elle n'est pas sur la pile et n'est pas désallouée parce que l'appel se termine. C'est le Free qui la libère explicitement. S'il n'y a pas de Free, cela fonctionne très bien.

    Citation Envoyé par PapyJohn Voir le message
    Pour que ton code soit bon il faut que la TsringList soit declarée precedement à l'appel
    voici une des solutions possibles
    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
     
    procedure TForm1.Button1Click(Sender: TObject);
    Var
     MesChoix : TstringList;
    begin
     MesChoix :=  TstringList.create ;
     combobox1.Items.AddStrings(liste(MesChoix));
     MesChoix.free
    end;
     
    function TForm1.liste(Var I: TlisteString) : TlisteString;
    begin
      l.Add('a');
      l.Add('b');
      l.Add('c');
    Result:=i
    end;
    Je n'ai pas tester mais a une faute de frappe pres cela doit etre bon
    On ne passe jamais une string list par référence (var), sauf quand on sait pertinemment ce qu'on fait. En effet, les objets sont déjà une référence vers des données sur le tas.

    Donc, certes, ce code va "fonctionner", parce qu'il va donner le résultat demandé, mais il est faux point de vue conception.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  10. #10
    Membre habitué
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2002
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mars 2002
    Messages : 147
    Points : 144
    Points
    144
    Par défaut Alors on fait comment?
    Merci pour ces éclairages, mais alors on fait comment finalement? En enlevant le var ça suffit?

    Bon, aprés test, ça marche sans le var

    Merci

  11. #11
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Pour ma part je procède généralement comme ceci :
    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
     
    function CreeListeMachin : TStringlist; //<- elle peut se trouver dans une unité quelconque
    begin Result:=TStringlist.create;
          Result.Add('tagada');
          Result.Add('abracadrabra');
          ...
          Result.Sort;
    end;
     
    // Utilisation + libération de la StringList, éventuellement dans une autre unité
    procedure TForm1.JutiliseLaStringListClick(Sender : TObject);
    var       SL : TStringList; 
    begin     SL:=CreeListeMachin;
              MonRichEdit.lines.Assign(SL);
              // et comme j'ai déclaré SL comme une var locale je la free ici
              SL.Free;
    end;
    // Par contre si je déclare SL en tant que var globale utilisée en divers 
    // endroits du code c'est à moi de savoir quand la SL n'a plus de raison 
    // d'exister pour la libérer.
    ... et je fais idem lorsque je crée par exemple un BitMap que je trimballe d'un endroit du code à une autre.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

Discussions similaires

  1. Problème de libération de la mémoire dans une fonction
    Par ArnaudFu1 dans le forum Débuter
    Réponses: 2
    Dernier message: 23/02/2012, 16h21
  2. Réponses: 1
    Dernier message: 07/10/2011, 10h21
  3. [Dojo] Invisibilité d'une CheckBox crée dans une fonction javascript
    Par hapalemur dans le forum Bibliothèques & Frameworks
    Réponses: 2
    Dernier message: 05/06/2009, 15h41
  4. Réponses: 8
    Dernier message: 14/12/2006, 23h37
  5. Transmission d'un objet crée dans une fonction
    Par EvilAngel dans le forum ASP
    Réponses: 2
    Dernier message: 10/05/2004, 20h19

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