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 :

Stack overflow avec Delphi 10.4.2 Sydney


Sujet :

Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2002
    Messages : 58
    Points : 150
    Points
    150
    Par défaut Stack overflow avec Delphi 10.4.2 Sydney
    Bonjour à tous,


    J'ai créé une base de données avec des clés permettant de créer un treeviev en Delphi avec FIREBIRD 3/0.
    En résumé ceci qui marche très bien sur un orddi Winows 10 qu j'appellerai "A".

    VBARIABLE|Variableprecedente6libelle
    exemple simplifié
    N° |N°précédent|N° précédent|nom
    1234|456|'SOLANUM'
    et avant dans la base
    456|123|"SOLANACEES"

    Et un programme récursif pour créer un treeview avec la base :
    Je précise : ça marche très bin sur un ordi portable "A" avec Delphi XE.3 Rio

    Mias là, sur un autre ordi que j'appellerais "B" juste un message d'erreur au lancement de la création du TreeView récursif
    "Erreur STACK OVERFLOW"
    Rien à faire depiuis 2 semaines. Donc je viens ici, on ne sait jamais.
    Soit je laisse le programme là ou ça marche, soit j'ai une réponse pour migrer vers Delphi Sydney sur un autre ordi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    //loquaége swwapOverflow
    function Recursive(Level : Integer) : Integer;
    begin
      try
        Level := Level + 1;
        Result := Recursive(Level);
      except
        on E: EStackOverflow do
          Result := Level;
      end;
    end;
    En clair : Quels sont les paramétrages de windows 10 et Delphi pour éviter le "stack overflow" en cas de base de données/programme récursifs.

    Merci d'avance si il y a quelqu'un qui a une idée
    Vadim

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Euh... La base des fonctions récursives reste de mettre une condition d'arrêt pour tout dépiler, là y a rien: tu t'appelles en boucle jusqu'à la fin du monde (ou un dépassement de capacité sur le integer).

  3. #3
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2002
    Messages : 58
    Points : 150
    Points
    150
    Par défaut En fait la boucle a une fin
    Non. La boucle récursive cesse quand l'item n'a pas de parent. (Renvoi de valeur "NULL" donc : pas de parent.
    Ce programme transposé sans changer la mondre ligne marche très bien sur un ordi W10 avec Delphi "Rio" mais "stack overflow sur un autre ordi W10 avec Delphi "Sydey"

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
     
      mark:=readstring('DATA','mark','NULL');
     
    VAR
       i:integer;
       Cpt:integer;
     
    Procedure CreeNoeudEnfant(Maitre:String);
    var
      j:Integer;
      stf:string;
      Begin
        If (maitre=mark) then
        Begin
          Dec(Niveau);
          Exit; //fin Totale
        End;
        Inc(Niveau);
          For j:=0 To Cpt-1 DO
            If (ListePrec[j]=Maitre) then
            Begin
              NoeudAuNiveau[Niveau]:=Tv2.items.AddChild(NoeudAuNiveau[Niveau-1],ListeLib[j]);
              CreeNoeudEnfant(ListeObj[j]);
            End;
         dec(Niveau);
       End;
     
     
     
    begin
       TRY
        TV2.Items.Clear;
        TV2.Items.BeginUpdate;
        Table1.DisableControls;
        ListeObj.clear;
        ListePrec.clear;
        ListeLib.clear;
      With table1 do
      Begin
         open;
         first;
         niveau:=0;
         cpt:=0;
         While Not table1.Eof do
         Begin
           ListePrec.Add(FieldByName(IdPreced).AsString);
           ListeObj.Add(FieldByName(IdentObj).AsString);
           ListeLib.Add(FieldByName(Nom).AsString);
           next;
         End;
      End;
          cpt:=ListeObj.count; //Nombre de noeuds en fait
          For i:=0 TO Cpt-1 DO Begin //Cherche
             If ListePrec[i]=mark then
             Begin
                 NoeudAuNiveau[0]:=Tv2.items.Add(nil,ListeLib[i]);
                 Inc(Niveau);
                 CreeNoeudEnfant(ListeObj[i]);
                 Break;
             end;
          end;
       TV2.Items.EndUpdate;
       Table1.EnableControls;
       ShowMessage('Succès : '+intTostr(TV2.Items.count)+' noeuds créés...');
      // instructions connexes pour libérer objets aux.
       EXCEPT
             ShowMessage('Echec');
             If not table1.Active then table1.Open;
       END;
     
    end;
     
    (* Pas indispensable, mais c'est plus prudent...*)
    procedure NettoieEnSortant;
    begin
         table1.close;
         table1:=nil;
         ListeObj.free;
         ListePrec.Free;
         ListeLib.Free;
    end;

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    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 036
    Points : 40 942
    Points
    40 942
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    ces listes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       ListeObj.clear;
        ListePrec.clear;
        ListeLib.clear;
    sont certainement créées quelque part mais où et comment et même pourquoi ?
    Il y a des années (D3+Firebird) que j'ai fait un truc sembable je n'ai jamais eu besoin de listes supplémentaires

    Mais là, sur un autre ordi que j'appellerais "B" juste un message d'erreur au lancement de la création du TreeView récursif
    Déjà le fait que cela soit sur un autre ordi, la première question que je me poserai : "j'ai bien accès à la base de donnéees et à la table ?" avant même d'incriminer TreeView.
    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

  5. #5
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Citation Envoyé par vadim Voir le message
    Non. La boucle récursive cesse quand l'item n'a pas de parent. (Renvoi de valeur "NULL" donc : pas de parent.
    Tant mieux, mais ça aurait fait gagner du temps si tu avais proposé le bon code source au départ au lieu du code sur lequel j'ai répondu et qui n'a pas de condition de sortie.

    Par rapport au bloc de code que tu as finalement copié j'ai une première remarque : "WITH, quelle plaie !". Vraiment illisible quand on a pas tout et que ce n'est pas proprement indenté.

    Pour la ligne d'affectation à "mark", je suppose que le ReadString provient d'un TIniFile. Est-ce le cas ? Es-tu sûr de la valeur qu'il récupère ?

    La condition de sortie de ta boucle est liée à la valeur de "master". Es-tu sûr qu'à un moment cette valeur y est ?

    As-tu tenté un débogage et éventuellement un point de suivi au niveau de l'entrée dans la procédure afin de vérifier que les données traitées sont cohérentes avec celles que tu dois avoir dans ta table ?

    Pourquoi utilises-tu 3 listes séparées plutôt qu'une seule avec des RECORD ou CLASS contenant les 3 valeurs ? Es-tu sûr que leur parcourt se fait de façon synchronisée ? Pas de "sort()" activé quelque part ?

    Concernant la procédure NettoieEnSortant, contrairement à ce que tu indiques en commentaire, c'est indispensable. Ca fait partie des bonnes pratiques de fermer les tables/fichiers que l'on ouvre et de libérer la mémoire que l'on utilise. La prudence n'a rien à voir là-dedans.

    Et tu peux retirer le "Table1:=nil" si ton Table1 est ajouté à ta fiche, ou alors gère le toi-même avec un TTable.Create en local comme tu le fais avec les listes. On ne supprimeras des composants de la fiche dans le source, on la laisse le faire quand on la supprime elle-même ou en fermeture de programme. Le contraire c'est à mon sens une erreur de logique dans le code.

    A part ces remarques, ton code semble cohérent à condition que les données le soient. Sans les données on ne peut pas te trouver de raison pour laquelle tu génères des débordements de pile. La différence 10.3.x / 10.4.x vient probablement d'une optimisation du compilateur qui détecte un truc qui ne se déclenchait pas dans l'autre version.

  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 : 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 430
    Points
    28 430
    Par défaut
    alors le code est pas génial, mais le problème bien très certainement de la valeur de "mark" puisque c'est la condition de sortie

    exemple de chose qui me semble douteuses: NoeudAuNiveau[]...il me semblerait plus judicieux d'ajouter un paramètre NoeudParent à CreeNoeudEnfant()
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre actif
    Homme Profil pro
    libre
    Inscrit en
    Juin 2019
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Juin 2019
    Messages : 205
    Points : 292
    Points
    292
    Par défaut
    Si les éléments dans ListePrec[x] et ListeObj[x] ont la même valeur la fonction entre dans une boucle infinie

  8. #8
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2002
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2002
    Messages : 58
    Points : 150
    Points
    150
    Par défaut Effectivement, c'était un souci de connexion
    Bon, ben voilà, suite à vos divers avis, et devant le fait que le code marche sur un autre ordi j'ai regardé de plus près la connexion.
    En fait j'ai migré de Firebird 2.5 a Firebird 3.0 comme base de données et j'avais oublié de copier la bonne dll dans le dossier system32.
    C'était tout bête. (Hem...) Cela connectait cependant à la base mais les paramètres renvoyés, notamment la marque de fin, étaient farfelus ou absents.
    Le programme tournait en rond au lieu de construire le TreeView.

    Souvent, la solution a un problème est la plus simpliste (Le fameux "Rasoir d'Occam")
    Il me reste maintenant à rendre le code plus élégant et simplifier un peu.

    Donc voilà, un gros merci à SergioMaster, Paul Toth et vous tous.

    Bonne journée à tous!

    Vadim

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    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 036
    Points : 40 942
    Points
    40 942
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Citation Envoyé par vadim Voir le message
    En fait j'ai migré de Firebird 2.5 a Firebird 3.0 comme base de données et j'avais oublié de copier la bonne dll dans le dossier system32.
    Qu'en dire sinon qu'il n'avait jamais été indiqué une quelconque utilisation de Firebird (sauf de ma part)
    et que une installation correcte de firebird n'aurait pas du posé ce souci de "bonne dll"
    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

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

Discussions similaires

  1. Stack overflow avec SQL Server Compact Edition
    Par phoenixgreg dans le forum Langage
    Réponses: 4
    Dernier message: 14/10/2016, 08h50
  2. Réponses: 1
    Dernier message: 19/10/2010, 09h01
  3. Réponses: 3
    Dernier message: 01/12/2009, 21h19
  4. " Stack overFlow " avec IE
    Par lion13 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 21/11/2007, 21h49
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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