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 :

Libération mémoire de contrôles créés dynamiquement dans un tableau ouvert


Sujet :

Delphi

  1. #1
    Membre actif
    Avatar de Jlmat
    Homme Profil pro
    Consultant en Ressources Humaines, Retraité passionné de programmation
    Inscrit en
    Avril 2008
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant en Ressources Humaines, Retraité passionné de programmation
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 284
    Points : 287
    Points
    287
    Par défaut Libération mémoire de contrôles créés dynamiquement dans un tableau ouvert
    Bonjour à tous,

    Éternel débutant je suis!
    Enfin je ne sais plus...
    j'ai créé un tableau ouvert de TcheckBox qui sont créés dynamiquement et se positionnent sur la Fiche en fonction du nombre d'options d'une procédure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Var
      FormSelectChamps : TFormSelectChamps;
      ListeBox        : array of TCheckBox;
     
    ...
     
    ListeBox[i] := TCheckBox.Create(FormSelectChamps);
    Dans la procédure Destroy de la Fiche, j'écris par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    procedure TFormSelectChamps.FormDestroy(Sender: TObject);
     var ii : integer;
    begin
      for ii := Low(ListeBox) to High(ListeBox) do ListeBox[ii].Destroy;
      SetLength(ListeBox,0);
    end;
    1. Est-ce correct?
    2. Est-ce que si je me contente de supprimer le tableau ListeBox avec Setlength, je vais du même coup libérer ses contenus qui ont été créés dynamiquement aussi?!? N'y aura t-il pas de fuite de mémoire?

    Merci
    Je programme en Lazarus 3.2.2 sous windows 10 pro

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    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 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        for ii := Low(ListeBox) to High(ListeBox) do 
           ListeBox[ii].free;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Membre actif
    Avatar de Jlmat
    Homme Profil pro
    Consultant en Ressources Humaines, Retraité passionné de programmation
    Inscrit en
    Avril 2008
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant en Ressources Humaines, Retraité passionné de programmation
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 284
    Points : 287
    Points
    287
    Par défaut
    Merci anapurna

    Ha oui Free à la place de Destroy, c'est mieux!
    Donc, si je comprends bien, SetLength ne suffit pas pour éviter les fuites de mémoires?!
    Je sais pas vérifier ce problème. Il semble que le débogueur de Delphi 10.3 ne signale pas le problème...

    A+
    Je programme en Lazarus 3.2.2 sous windows 10 pro

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par Jlmat Voir le message
    Donc, si je comprends bien, SetLength ne suffit pas pour éviter les fuites de mémoires?!
    Non, SetLength(0) ne libère rien si ce n'est sa propre liste de ... ! Ici, une liste de pointeurs.

    Mais la fiche contient une liste de tous les composants qui lui sont rattachés (de prêt ou de loin) et lance automatiquement leur destruction lorsque elle-même est détruite. Il n'y a aucune raison que l'EDI te signale une fuite quelconque. A ce stade, SetLength(Listbox, 0) seul est correct.

    Cela dit, si Listbox (array of) appartenait à la fiche, tu n'aurais même rien à faire puisque en plus de détruire ses composants, elle libérerait aussi cette allocation

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    j'ai pris l'habitude d'indiquer un parent aux composants que je crée. Parent est différent de Owner (surtout depuis FMX je dois dire).
    Quant au ListBoxArray j'aurais mis pareil un ListBoxArray.free; ou FreeAndNil(ListBoxArray)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Membre confirmé
    Avatar de alheuredudejeuner
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2005
    Messages : 376
    Points : 632
    Points
    632
    Billets dans le blog
    4
    Par défaut tobjectlist
    Bonjour,

    pourquoi ne pas utilise un tobjectlist qui libère les objet qu'il contient sans code si il à les potions par défaut ?

    Cordialement

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    comme le dit Andnotor, il suffit de placer le tableau dans la fiche est il n'y a rien à faire, c'est un tableau dynamique qui sera détruit et les checkbox seront détruites par leur parent ou owner.

    il est également possible d'avoir une autre approche, placer les composants à la souris et initialiser le tableau au chargement

    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
     
    procedure TForm1Create(Sender: TObject);
    var
      Index: Integer;
      Count: Integer;
    begin
      SetLength(ListeBox, ControlCount); // préallouer suffisamment de place (si la valeur n'est pas connue)
      Count := 0;
      for Index := 0 to ControlCount - 1 do
      begin
        if Controls[Index] is TCheckBox then
        begin
          ListeBox[Count] := TCheckBox(Controls[Index]);
          Inc(Count);
        end;
      end;
      SetLength(ListeBox, Count); // fixer la taille réelle du tableau
    end;
    car j'imagine que le but est d'accéder aux CheckBox par un index.

    Et si le nombre est connu

    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
     
    procedure TForm1Create(Sender: TObject);
    var
      Index: Integer;
      Count: Integer;
    begin
      SetLength(ListeBox, 10);
      Count := 0;
      for Index := 0 to ControlCount - 1 do
      begin
        if Controls[Index] is TCheckBox then
        begin
          Assert(Count < 10, 'Il y a plus de 10 CheckBox sur la fiche');
          ListeBox[Count] := TCheckBox(Controls[Index]);
          Inc(Count);
        end;
      end;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Sinon, tu as la TComponentList, qui s'occupe de gérer le retrait des composants si ils sont détruits par la fiche (cf. FreeNotification), ce qui te permet de bien libérer ta mémoire si tu as des composants non présents sur ta fiche, et de ne pas libérer ceux qui l'ont déjà été.

  9. #9
    Membre actif
    Avatar de Jlmat
    Homme Profil pro
    Consultant en Ressources Humaines, Retraité passionné de programmation
    Inscrit en
    Avril 2008
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant en Ressources Humaines, Retraité passionné de programmation
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 284
    Points : 287
    Points
    287
    Par défaut
    Merci à tous pour vos réponses détaillées!


    Cela dit Andnotor me permet de ne pas me casser la tête:
    ce stade, SetLength(Listbox, 0) seul est correct.

    Cela dit, si Listbox (array of) appartenait à la fiche, tu n'aurais même rien à faire puisque en plus de détruire ses composants, elle libérerait aussi cette allocation
    à Sergio,
    j'ai pris l'habitude d'indiquer un parent aux composants que je crée. Parent est différent de Owner (surtout depuis FMX je dois dire).
    Oui, c'est ce que je fais aussi!

    à Paul TOTH

    toujours plus fort dans "on se la cool douce!"

    comme le dit Andnotor, il suffit de placer le tableau dans la fiche est il n'y a rien à faire, c'est un tableau dynamique qui sera détruit et les checkbox seront détruites par leur parent ou owner.
    Je suis un peu du genre fainéant, mdr!
    Comme tout est créé sur la Fiche, on vire tout et je me contente du close!
    jlmat
    Je programme en Lazarus 3.2.2 sous windows 10 pro

  10. #10
    Membre actif
    Avatar de Jlmat
    Homme Profil pro
    Consultant en Ressources Humaines, Retraité passionné de programmation
    Inscrit en
    Avril 2008
    Messages
    284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant en Ressources Humaines, Retraité passionné de programmation
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 284
    Points : 287
    Points
    287
    Par défaut
    à Paul

    C'est amusant en te relisant en détail,

    il est également possible d'avoir une autre approche, placer les composants à la souris et initialiser le tableau au chargement
    Je suis justement en train d'écrire une procédure pour faire ça avec attraction automatique pour un arrangement automatique dans un tableau en forme d'image.
    j'utilise pour cela la technique visuelle du dragdrop!
    Je serais prêt à mettre le source, mais c'est juste un petit exemple, j'avais penser le mettre sur "comment ça marche"

    J'ai pas trop envie pour l'instant de rédiger un tuto détaillé. Je me réserve cela pour plus tard.

    A+
    Je programme en Lazarus 3.2.2 sous windows 10 pro

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/12/2014, 13h16
  2. Réponses: 5
    Dernier message: 05/05/2011, 11h10
  3. Garder contrôles créés dynamiquement
    Par roshy dans le forum ASP.NET
    Réponses: 5
    Dernier message: 06/07/2010, 14h13
  4. Accès à des contrôles créés dynamiquement
    Par sphynxounet dans le forum VB.NET
    Réponses: 1
    Dernier message: 12/08/2009, 20h34
  5. Gerer les evenements de Contrôles créés dynamiquement
    Par celineSGH dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 29/12/2008, 02h25

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