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 :

TList de Tlist


Sujet :

Delphi

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut TList de Tlist
    Bonjour,
    Je vous explique mon problème: J'ai besoin d'une liste de record contenant elle-même une liste de record (je sais, j'aurais du faire une collection ).
    En revanche, quand j'appelle Detruit_Liste, ça ne libère pas totalement la mémoire allouée!
    Si qqun aperçoit un bug, merci bcp, moi je suis dessus depuis hier!!

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    type Tgenerale = record
       nom: String;
       attribut: String;
       liste: TList;
    end;
    Pgenerale=^Tgenerale;
     
    type Tsecondaire = record
       numero: Integer;
       nom: String;
    end;
    Psecondaire=^Tsecondaire;
     
    var lstGenerale = TList;
     
     
    procdure Remplit_Liste;
    var i: Integer;
         MonPgenerale: Pgenerale;
         MonPSecondaire: Psecondaire;
    begin
       New(MonPgenerale);
       Pgenerale(MonPgenerale)^.Nom:= 'Liste Generale';
       Pgenerale(MonPgenerale)^.liste:= TList.create;
       for i:=0 to 1000 do
       begin
          New(MonPsecondaire);
          PSecondaire(MonPSecondaire)^.numero:= i;
          PSecondaire(MonPSecondaire)^.nom:= 'toto';
          Pgenerale(MonPgenerale)^.liste.Add(MonPsecondaire);
       end;
       lstGenerale.Add(MonPgenerale);
    end;
     
    procdure Detruit_Liste;
    begin
       while lstGenerale.Count<>0 do begin
          while Pgenerale(MonPgenerale)^.liste.Count<>0 do begin
             Dispose(Pgenerale(MonPgenerale)^.liste[0]);
             Pgenerale(MonPgenerale)^.liste.Delete[0];
          end;
         Pgenerale(MonPgenerale)^.liste.Free;
     
          Dispose(lstGenerale[0]);
          lstGenerale.Delete[0];
       end;
     
       lstGenerale.Free;
    end;

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Salut

    Avant tout, quelques remarques :
    - évite, dans la mesure du possible, de faire des cast avec les pointeurs, ils ne servent pas à grand chose.
    - définis, dans la mesure du possible, des classes pour éviter la programmation avec des variables globales (pour améliorer l'encapsulation et donc la maîtrise à long terme de ton code)
    - tu dois avoir une variable globale MonPgenerale qui perturbe ton programme.

    Ma solution pour la destruction :
    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
     
    procedure Detruit_Liste;
    begin
      while lstGenerale.Count<>0 do 
      begin
        with lstGenerale[0]^ do
        begin
          while liste.Count<>0 do 
          begin
            Dispose(liste[0]);
            liste.Delete[0];
          end;
          liste.Free;
        end;
        Dispose(lstGenerale[0]);
        lstGenerale.Delete[0];
      end;
      lstGenerale.Free;
    end;
    Je pense que c'est l'utilisation de la variable MonPgenerale qui t'as planté

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  3. #3
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    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
     
    procedure Detruit_Liste;
    var  i,j:integer;
    begin
      for i:=0 to  lstGenerale.Count-1 do 
      begin
        with lstGenerale[i] do // pas la pein de ^
        begin
          for j:=0 to liste.Count-1 do 
          begin
            Dispose(PSecondaire(liste[j])); //ou freemem(liste[j],sizeof(PSecondaire)); liste[j] est un pointeur sans pécification de memoir résérver
           //pas la peine liste.Delete[0]; free fait le netoiyage 
          end;
          liste.Free;
        end;
        Dispose(Pgenerale(lstGenerale[i])); 
      end;
      lstGenerale.Free;
    end;

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut
    Bon, je savais pas que le cast avec les pointeurs était déconseillé!
    Pour la classe, oui, c'est évident, j'ai juste extrait ce bout de code pour bien qu'on comprenne le problème.
    Par contre, je comprends pas bien ce que tu veux dire par "c'est ta variable globale qui fait planter"

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Concernant les remarques d'Edam, c'est parfaitement vrai mais je voulais conserver une partie du code d'origine et ne pas introduire trop de choses à la fois.

    Les cast ne sont pas déconseillés mais il ne servent à rien en l'espèce.

    Pour la variable globale, je l'ai déduis car tu utilise une variable non déclarée.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut
    Citation Envoyé par e-ric
    Concernant les remarques d'Edam, c'est parfaitement vrai mais je voulais conserver une partie du code d'origine et ne pas introduire trop de choses à la fois.

    Les cast ne sont pas déconseillés mais il ne servent à rien en l'espèce.

    Pour la variable globale, je l'ai déduis car tu utilise une variable non déclarée.

    cdlt

    e-ric
    T'es sûr que ton code marche?
    Chez moi, il plante dès le with...

  7. #7
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    de quel code parl tu??

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Même question car le code d'Edam n'est pas exactement le même que le mien, qu'est-ce qui plante : la compilation ou l'exécution ? quelle est l'erreur ?

    Rem : je n'ai pas testé le code que je t'ai proposé.

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  9. #9
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    Citation Envoyé par e-ric
    Même question car le code d'Edam n'est pas exactement le même que le mien, qu'est-ce qui plante : la compilation ou l'exécution ? quelle est l'erreur ?

    Rem : je n'ai pas testé le code que je t'ai proposé.

    e-ric
    ni le mien

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut
    Non, rassurez-vous, ça ne plante pas, c'était de ma faute
    Par contre, toujours le même problème qq soit le code: vous pouvez faire le test vous mettez 2 boutons l'un pour remplir, l'autre pour détruire:
    Vous verrez que la mémoire ne se libère pas!
    yé né comprends pas

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 573
    Par défaut
    Comment as-tu fait pour détecter la fuite de mémoire ? C'est vraiment cette partie de code qui est à l'originie de la fuite ?
    Peux-tu la quantifier ?

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut
    Ouf, j'ai trouvé, finalement, c'est edam qui avait bon(n'est pas membre chevronné qui veut!):

    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 Detruit_Liste;
    var  i,j:integer;
    begin
      for i:=0 to lstGenerale.Count-1 do
      begin
        with Pgenerale(lstGenerale[i])^ do // pas la pein de ^
        begin
          for j:=0 to liste.Count-1 do
          begin
            Dispose(PSecondaire(liste[j])); 
          end;
          liste.Free;
        end;
        Dispose(Pgenerale(lstGenerale[i]));
      end;
      lstGenerale.Free;
    end;
    Le pb venait que je faisais un Dispose de la TList sans le caster avec son type (bizarre que le compilateur ne le signale pas!)
    En revanche, j'ai du légérement modifié son code (avec le with Pgenerale(lstGenerale[i])^) car le compil me remontait les bretelles (record or object attendu).
    En tout cas, merci pour votre aide!

  13. #13
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 159
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 159
    Par défaut
    Yep !
    Ouf, j'ai trouvé, finalement
    Ça c'est bien !
    Ce qui l'est un peu moins, c'est de nous laisser sur notre faim, car il y avait dans
    les posts précédents un truc intéressant (enfin, tout au moins pour moi :
    Comment as-tu fait pour détecter la fuite de mémoire ?
    Merci de satisfaire cette curiosité qui sera sûrement utile !
    --
    jp

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2003
    Messages : 42
    Par défaut
    Mais tout simplement en vérifiant l'état de la mémoire après libération de la TList!

  15. #15
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 159
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 159
    Par défaut
    Mais tout simplement en vérifiant l'état de la mémoire après libération de la TList!
    Certes, certes, mais comment ?
    Avec des MemoryStatus et ce genre de choses,
    ou bien existe-t-il des trucs plus sophistiqués ?
    --
    jp, complètement ignorant en la matière, là !

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

Discussions similaires

  1. TList de TList
    Par olisg1 dans le forum C++Builder
    Réponses: 2
    Dernier message: 12/02/2013, 10h02
  2. [TList] Double référencement
    Par Pedro dans le forum Langage
    Réponses: 5
    Dernier message: 28/07/2004, 13h14
  3. TList et redimensionnement ?
    Par cpdump dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2004, 16h54
  4. TList lente
    Par localhost dans le forum C++Builder
    Réponses: 5
    Dernier message: 17/02/2004, 01h01
  5. Transtyper element d'1 variable pointant sur TList?
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 25/02/2003, 22h53

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