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 :

Sérieux pépin d'algorithme sur une boucle et deux Tlist


Sujet :

Delphi

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut Sérieux pépin d'algorithme sur une boucle et deux Tlist
    Bonsoir à tous

    J'ai deux TList de structures ( les types et variables sont plus bas). Et, lors d'une comparaison en boucle, j'ai ce message d'erreur :



    Classique. Oui, mais où ?? Avec le débogueur, j'ai localisé la fonction d'où provient l'erreur. Mais à l'intérieur de cette fonction : où est le bug ? J'ai débogué des heures durant avec un fichier LOG, et des fichiers listant les valeurs des variables, etc. Il me faudrait fixer un point d'arrêt conditionnel sur l'erreur : http://docwiki.embarcadero.com/RADSt...d%27arr%C3%AAt

    Malheureusement, XE7 me le refuse (la commande apparaît en grisé dans le menu). Pourquoi ? Je ne sais pas.

    Voici les types et variables :

    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
     
    Type
          Infos_F = record
            Nom_Cplt_F : array [0..255] of char;
            Nom_Court_F : array [0..255] of char;
            Date_Der_Modif : TDateTime;
          end;
     
     
    Var
          Lst_Infos_F : TList;    // Pr essais et non utilisée ici
          Lst_Infos_F_Source : TList;
          Lst_Infos_F_Dest : TList;
     
          Idx_Lst_Source : integer;  // Index des TList
          Idx_Lst_Dest : integer;
     
          Ptr_Infos_Fic : ^Infos_F;   // Ptr sur une structure de type Infos_F
          Date_Der_Acces : TDAteTime;
          Date_F_Trouve_Ds_Lst_Infos_F_Dest : TDateTime;
     
          Rep_Source : string;
          Rep_Dest : string;
     
          Lst_F_Ds_Source : TStringList;  // StringList chargeant le répertoire source
          Lst_F_Ds_Dest : TStringList;		// StringList chargeant le répertoire dest
    La procédure "pilote", qui commande tout le processus :

    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
    
    Procedure Pilote_Simulation_Copie;
    begin
    
        // CHARGER DS LES TStringList LES DEUX REPERTOIRES A COMPARER
    
        Charger_Rep_Source;
        Charger_Rep_Dest;
    
        // CREER LES TLIST Lst_Infos_F_Source et Lst_Infos_F_Dest
        Creer_Liste_Infos_F_Source;
        Creer_Liste_Infos_F_Dest;
    
        // LIBERER LES TsTringList DEVENUES INUTILES  ---------------------------
        if ASSIGNED (Lst_F_Ds_Source) then Lst_F_Ds_Source.Free;
        if ASSIGNED (Lst_F_Ds_Dest) then Lst_F_Ds_Dest.Free;
    
    // Jusque là, aucun problème
    
        { SUPPRIMER DE Lst_Infos_F_Source LES FICHIERS N'EXISTANT PAS DANS Lst_Infos_F_Dest
        et ce AVEC LA MEME AROBERSCENCE : ils sont deja sauvegardés, on n'y touche pas }
        Boucle_Purger_TList_Source_Des_F_Existant_Ds_TList_Dest;  // C'est  que la bât blesse !!
    
    		// etc...
    		
    end;
    Et la fonction coupable :
    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
     
     
    Procedure Boucle_Purger_TList_Source_Des_F_Existant_Ds_TList_Dest;
    Var   i : integer;
          Nom_F_Source_Sans_Drive : string;
          Nom_Cplt_F_Ds_TList : string;
          Nom_Cplt_Sans_Drive : string;
     
    begin
     
    {
    - Pointer le premier élément de Lst_Infos_F_Dest.
     
    - Cet élément existe-t-il dans l'un des items de Lst_Infos_F_Source ?
       -> SI OUI : supprimer l'item ds Lst_Infos_F_Source
     
    - Fichier ds Lst_Infos_F_Source est PLUS RECENT que son corrolaire ds Lst_Infos_F_Dest ?
       -> SI OUI : ne pas supprimer l'item : c'est un fichier à copier
       -> SI NON : supprimer l'item de Lst_Infos_F_Source
     
    - Faire la même chose pour tous les items de la Lst_Infos_F_Source (sans dépasser le Nb d'items de Lst_Infos_F_Dest)
    }
     
        for i := 0 To Lst_Infos_F_Source.Count -1 do
          begin
              Idx_Lst_Source := i;
              if i <= Lst_Infos_F_Dest.Count then  // Ne pas dépasser la limite de Lst_Infos_F_Dest
              begin
                Ptr_Infos_Fic := Lst_Infos_F_Source.Items[i]; // Pointer l'item ds Lst_Infos_F_Source
                Nom_Cplt_F_Ds_TList := Ptr_Infos_Fic.Nom_Cplt_F;  // Correct (vérifié)
                Nom_Cplt_Sans_Drive := Nom_F_Sans_Drive(Nom_Cplt_F_Ds_TList); // Correct (vérifié)
     
                // Chercher un item corrolaire ds Lst_Infos_F_Dest (corrolaire = même nom de fichier, même arborescence)
                Idx_Lst_Source := i; // Idx_Lst_Source, var globale, a la même valeur que Idx_Local_TList_Source (locale)
                if Item_Existe_Ds_Lst_Infos_F_Dest(Nom_Cplt_Sans_Drive) = True then  // La Fn va utiliser Idx_Lst_Source, d'où l'affectation ligne précédente
                  begin
                      if F_Source_Plus_Recent_Que_F_Dest(Ptr_Infos_Fic.Date_Der_Modif, Date_F_Trouve_Ds_Lst_Infos_F_Dest) = False then
                        begin
                            Lst_Infos_F_Source.Delete(Idx_Lst_Source); // Eliminer cet item de Lst_Infos_F_Source
                            Dispose(Lst_Infos_F_Source.Items[Idx_Lst_Source]);  // Libérer la mémoire qu'il occupait
                        end;
                  end
                Else // Pas d'item corrolaire : on garde l'item ds Lst_Infos_F_Source, puisque l'on va copier le fichier
                  begin
                      // Rien.
                  end;
              end; // If Idx_Local_TList_Source < Lst_Infos_F_Dest.Count
          end;
     
    end;
    Bon. Mon code n'est pas des plus élégants ni des plus optimisés Mais c'est à venir. Et surtout, j'aime me relire facilement. Si ça continue, je vais devoir y aller avec les pavés, les itérations et les flèches.

    Où est-ce que je me plante comme ça ?

    Merci

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Lst_Infos_F_Source.Count n'est pas réinterprété à chaque itération, supprimer un élément ne modifie pas la borne supérieure. Pour éviter cette erreur, il suffit de faire une boucle descendante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i := Lst_Infos_F_Source.Count -1 downto 0 do

  3. #3
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    OK...

    C'est ce que je fais pour la désallocation de la TLIst. Je ne l'ai pas fait là. Je donne le retour.
    En plus, j'avais interverti le Dispose et le Delete.

    Ca ne plante donc plus au même endroit. On avance

Discussions similaires

  1. question sur une boucle et un break
    Par isidore dans le forum C
    Réponses: 10
    Dernier message: 22/11/2006, 20h26
  2. [68HC11] Blocage sur une boucle
    Par paterson dans le forum Autres architectures
    Réponses: 3
    Dernier message: 10/11/2006, 20h45
  3. [VBA-E]PB sur une boucle for each next
    Par rond24 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 31/07/2006, 15h47
  4. Réponses: 11
    Dernier message: 19/06/2006, 16h54
  5. Problème sur une boucle
    Par Mateache dans le forum ASP
    Réponses: 6
    Dernier message: 31/01/2006, 09h48

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