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érer de la mémoire un boolean crée dynamiquement?!


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut Libérer de la mémoire un boolean crée dynamiquement?!
    Bonjours a tous,

    Avant de vous exposer mon problème je tiens a vous remercier d'avance pour toute l'aide que vous pourriez m'apporter.

    Revenons au problème

    J'utilise un tableau d'un record Tbonhomme crée/géré dynamiquement comme voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     type Tbonhomme = Record
        label_nick : TLabel;
        image : Timage;
        connected : Boolean;
      End;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tableau_bonhomme : Array of Tbonhomme; // Je le déclare dans private
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure FreeBonhomme(nicks : array of Tbonhomme); // Je déclare la procédure pour libérer la mémoire
    Je crée dynamiquement mes composants...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SetLength(tableau_bonhomme, n);
    for i := 0 to n - 1 do begin
       with(tableau_bonhomme[i]) do begin
       label_nick := Tlabel.Create(nil);
       image := Timage.Create(nil);
       connected := false;
     end;
    Et maintenant la procédure pour libérer la mémoire...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.FreeBonhomme(nicks: array of Tbonhomme);
    var i: Integer;
    begin
     for i := Low(nicks) to High(nicks) do begin
     with(nicks[i]) do begin
       lbl_nick.Free;
       lbl_nick := nil;
       image.Free;
       image:= nil;
       connected ;// ICI QUE FAIRE ?!?
     end;
     end;
    Pour résumer, j'aimerai savoir comment désalouer mes booléens crées dynamiquement ?

    Impossible de faite bien sur un "connected.Free;" ça serait trop simple...

    Merci de votre aide

    Romain A

  2. #2
    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

    je dirais de laisser ton booléen tranquille et de t'attaquer plutôt au tableau en fin de boucle 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
    procedure TForm1.FreeBonhomme(nicks: array of Tbonhomme);
    var i: Integer;
    begin
     for i := Low(nicks) to High(nicks) do begin
     with(nicks[i]) do begin
       lbl_nick.Free;
       lbl_nick := nil;
       image.Free;
       image:= nil;
       //connected ;// ICI QUE FAIRE ?!?
     end;
     end;
     SetLength(nicks, 0);
     ...

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Merci ça marche impec

  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
    vu que ton tableau il est détruit à la fin, tu pourrais t'épargner d'écrire ces lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lbl_nick := nil;
    image:= nil;

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Tout a fait

    Merci encore. Bonne journée

  6. #6
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    pour répondre à la question tout de même...le boolean est alloué directement par le tableau, ce n'est qu'un octet en mémoire. De même que 4 octets sont alloués pour lbl_nick et 4 autres pour image afin d'y stocker l'adresse de l'instance des objets créés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // ceci alloue "n" fois 4+4+1 octets
     SetLength(tableau_bonhomme, n);
     for i := 0 to n - 1 do begin
       with(tableau_bonhomme[i]) do begin
       // place l'adresse retournée par le create dans les 4 permiers octets
        label_nick := Tlabel.Create(nil);
       // place l'adresse retournée par le create dans les 4 octets suivants
        image := Timage.Create(nil);
      // place 0 dans le 9 ième octet
        connected := false;
       end;
    et comme on boucle sur le tableau, on reprend le traitement avec les 9 octets suivant dans le tableau à chaque fois.

    du coup la libération c'est bien de détruire les objets dont les adresses ont été stockées dans label_nick et image, mais c'est le SetLengh(...,0) qui va libérer les séries de 9 octets, sans se préoccuper de leur contenu (nil, true, false...peu importe)

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Ok, donc si j'ai bien tout suivie

    Lors de l'utilisation de tableau de composotans (ou de record)

    1) on boucle sur le tableau pour libéré les composants eux même (ou les éléments du record)

    2) on supprime le tableau par un SetLength(mon_tableau,0)

    Et le travail est fait proprement sans fuite mémoire ?

    Petit remarque concernant un problème de syntaxe surement, dans mon exemple j'utilise un tableau d'un record comme expliquer plus haut, une procédure nommée FreeBonhomme(nicks: array of Tbonhomme) que j'appelle au moment opportun par un FreeBonhomme(mon_tableau_bonhomme).
    Le problème vient dans le code de la procédure FreeBonhomme :

    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 TForm1.FreeBonhomme(nicks: array of Tbonhomme);
    var i: Integer;
    begin
     for i := Low(nicks) to High(nicks) do begin
     with(nicks[i]) do begin
       lbl_nick.Free;
       lbl_nick := nil;
       image.Free;
       image:= nil;
     end;
     end;
    SetLength(nicks,0); // <<< Ici vient une erreur : "Type incompatible"
    end;
    Je ne comprend pas pourquoi le type serait incompatible car nicks correspond bien a mon tableau de composant ..

    Tout se passe comme si mon tableau nicks était dissocié de mon_tableau_bonhomme

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Déclare ta procédure comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure TForm1.FreeBonhomme(var nicks: array of Tbonhomme);
    Explications : dans ta version, le tableau est passé en tant que constante donc tu ne peux pas le modifier, par contre en ajoutant le var, tu indiques que le tableau peut être modifié à l'intérieur de ta procédure (si tu regarde la définition de SetLength tu pourras voir que le paramètre du tableau est lui aussi passé avec var). C'est ce qu'on appelle passer un paramètre par référence.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Salut Aka Guymelef,

    J'ai modifié mon code selon tes conseilles : la déclaration de la procédure dans la rubrique private

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     procedure FreeBonhomme(var nick: array of Tbonhomme);
    Ensuite la procédure elle même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TForm1.FreeBonhomme(var nick: array of Tbonhomme);
    var i: Integer;
    begin
     for i := Low(nick) to High(nick) do begin
     with(nick[i]) do begin
       lbl_nick.Free;
       lbl_nick := nil;
       image.Free;
       image:= nil;
     end;
     end;
    SetLength(nick,0); //Toujours le message d'erreur : E2006 Type imcompatible
    end;
    Une autre solution ??

    PS : j'utilise Delphi 2007

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Bon alors après essayage de tout ça sous Delphi (7 ) voila ce qu'il faut faire :

    En fait "l'astuce" réside dans le fait que tu dois faire de la déclaration de ton tableau un type de donnée, pour ce faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      TBonhommeArray = array of Tbonhomme;
    Et la déclaration de la procédure devient comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure FreeBonhomme(var nick: TBonhommeArray);
    Note aussi que ça compile également sans mettre le var mais je ne suis pas sûr qu'on ait réellement les mêmes effets, surtout après être sortit de la procédure, à voir !

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 16
    Points : 10
    Points
    10
    Par défaut
    Super merci ça fonctionne au poil

    A bientôt.

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

Discussions similaires

  1. [xslt]Comportement d'un noeud crée dynamiquement
    Par Capt. Flame dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 21/11/2005, 16h10
  2. Centrer un texte sur une image créée dynamiquement
    Par rigolman dans le forum Langage
    Réponses: 7
    Dernier message: 11/10/2005, 17h22
  3. Problèmes avec une TForm créée dynamiquement
    Par Pascal Jankowski dans le forum Composants VCL
    Réponses: 5
    Dernier message: 30/03/2005, 11h55
  4. Composant crée dynamiquement & Access in invalid memory
    Par Sunchaser dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/02/2005, 01h03
  5. Réponses: 5
    Dernier message: 12/07/2004, 21h00

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