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 Java Discussion :

StackOverFlow et boucle de rafraichissement


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2013
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2013
    Messages : 74
    Par défaut StackOverFlow et boucle de rafraichissement
    Bonsoir,

    J'ai un tableau bi-dimensionnel de calculs et lorsqu'une cellule est modifiée, si elle fait référence à une autre cellule le résultat de celle-ci doit être changé.
    Pour cela, jai fait une simple boucle imbriquée for parcourant ce tableau afin de rafraîchir les résultats. Cela fonctionne, seulement voilà, au bout d'un moment j'obtiens un StackOverFlow. Alors, il y a-t'il des précautions à avoir lorsqu'on fait ce genre de boucle ?

    Merci.

  2. #2
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Bonjour,

    on peut supposer que ta méthode de rafraichissement s'appelle, plus ou moins directement, dès lors qu'elle modifie quelque chose et que tu dois modifier quelque chose à chaque fois qu'elle est appelée. Ce qui résulterait en un appel récursif sans fin et donc à ton StackOverFlow.

    Mais tout cela reste de la divination. Pourrais-t-on avoir un peu de concret (genre, du code)?

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    on obtient une stackOverFlow lors du traitement lorsque la stack java est trop petite pour réaliser une boucle récursive. elle est forcément trop petite lors d'une boucle sans condition d'arrêt de récursion, comme dans l'exemple suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int getValeur() {
         return getValeur();
    }
    ici la méthode getValeur() s'appelle elle-même : à chaque appel, on empile un contexte, et comme elle s'appelle elle même, elle s'appelle sans cese elle-même, jusqu'à ce qu'on dépasse les capacités de la pile

    la précaution à prendre est donc de toujours veiller à avoir une condition d'arrêt qui est nécessaire vraie à un moment, tout en s'assurant de ne pas avoir un nombre de récursion trop importante pour la pile ou avoir une pile suffisamment grande.

    dans ton cas, en particulier, il faut évider les appels "ping-pong", comme par exemple :

    A1=A2+1;
    A2=A1+1;

    on peut détecter ce genre d'appel, en utilisant une pile par exemple qui mémorise chaque cellule utilisée, et qui renvoit une erreur particulière lorsqu'on détecte dans le set une cellule déjà utilisé : on affiche dans la cellule l'erreur à la place du bon résultat, afin d'avertir l'utilisateur que sa formule est incalculable

    exemple bidon
    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
     
    public class Cellule {
     
    ...
     
    public ValeurCellule getValeur() {
         if ( isFormule() {
             return calcule(new HashSet<Cellule>());
         }
         else {
             return valeur;
         }
    }
     
    public Resultat calcule(Stack<Cellule> pileCellules) {
        List<Cellules> cellulesAppelees = getFormule().getCellules();
        for(Cellule celluleAppelee : cellulesAppelees ) {
            if ( pileCellules.contains(celluleAppelee) ) {
               return new ResultatErreur("appel récursif " +celluleAppelee); // condition d'arrêt
            }
            cellules.push(celluleAppelee);
        }
        try{
           return getFormule().calcule(cellules);
        }
         finally {
              for(Cellule celluleAppelee : cellulesAppelees ) {
                  cellules.pop();
              }     
         }
     
    }
    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
    public class Formule {
     
         public Resultat calcule(Stack<Cellule> cellules) {
     
                List<Cellules> cellulesFormules=getCellules();
                List<ValeurCellule> resultats=new ArrayList<ValeurCellule>();
                for( Cellule cellule : cellulesFormules ) {
                    ValeurCellule resultat=cellule.isFormule()?cellule.calcule(cellules):cellule.getValeur();
                    if ( resultat instance Erreur ) {
                         return (Resultat)resultat,
                    }
                    resultats.add(resultat);
                }
                return calculeFormule(resultats);
         }
     
     
    }
    avec Resultat qui étend ValeurCellule et ResultatErreur qui étend Resultat bien sûr...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2013
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2013
    Messages : 74
    Par défaut
    Merci pour cette réponse détaillée, ça va nécessiter un temps d'étude et de tentatives sur Eclipse pour maitriser tout cela. Mais c'est ainsi qu'on apprend.

Discussions similaires

  1. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 12h45
  2. Rafraichissement de la fenêtre pendant une boucle
    Par Swann dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 30/05/2006, 00h09
  3. Probleme de rafraichissement d'un BDGrid
    Par marmotte dans le forum Bases de données
    Réponses: 10
    Dernier message: 28/05/2004, 18h07
  4. Timage rafraichissment
    Par Rizzla dans le forum Composants VCL
    Réponses: 5
    Dernier message: 16/09/2002, 17h08
  5. Réponses: 2
    Dernier message: 29/05/2002, 20h43

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