Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1597 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  exception StackOverflowError

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

exception StackOverflowError

n°661868
droopy 76
Posté le 03-03-2004 à 11:36:13  profilanswer
 

Bonjour,
 
j'ai un probleme avec une fonction reccursive.
Le code s'exécute mais, il arrive un moment où l'exception  
StackOverflowError est levée. Je me demande si cette erreur n'est pas liée à la mémoire virtuel.
 
Le code est le suivant :
private void getPartImage(int cSel,int x,int y,int w,int h) {
   
  int yy,xx;
  xx = x + 1;
  yy = y;
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
   }
  }
   
  xx = x + 1;
  yy = y - 1;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
     
    getPartImage(cSel,xx,yy,w,h);
     
     
   }
  }
 
  xx = x;
  yy = y - 1;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
     
     
   }
  }
   
  xx = x - 1;
  yy = y - 1;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
   }
  }
   
  xx = x - 1;
  yy = y ;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
 
   }
  }
   
  xx = x - 1;
  yy = y + 1;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
     
   }
  }
   
  xx = x ;
  yy = y + 1 ;
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
 
   }
  }
   
  xx = x + 1;
  yy = y + 1;
 
   
  if (xx < w && yy < h && yy >=0 && xx >= 0) {
   if (iPix[yy * w + xx] == cSel) {
    iPix[yy * w + xx] = -255;
    vPix.add(new Dimension(xx,yy));
    getPartImage(cSel,xx,yy,w,h);
         
   }
  }  
   
   
 }
 
Le principe est de délimiter une zone de mon tableau dont les valeurs sont identiques et délimités par des valeurs différentes dans le tableau.
Si quelqu'un pouvait m'indiquer m'aider sur ce pb Merci

mood
Publicité
Posté le 03-03-2004 à 11:36:13  profilanswer
 

n°661915
nraynaud
lol
Posté le 03-03-2004 à 12:13:22  profilanswer
 

J'ai pas lu le code de ta méthode (trop longue à mon gout) mais une chose est sure : c'est la condition d'arrêt de la récursivité qui n'arrête pas le traitement.
 
normalement, on fait ça avec l'algorithme du peintre, qu'on dérécursivise (en utilisant une pile explicite) pour des raisons de lisibilité.


---------------
trainoo.com, c'est fini
n°661922
droopy 76
Posté le 03-03-2004 à 12:24:59  profilanswer
 

Disons que le code est un gros brouillon. Normalement la fonction doit s'arrêter forcément à un moment donné par contre le nombre d'appel doit être supérieur à une limite qui déclenche une exception.
J'ai fait un test avec la fonction void essai() { it++ ; if (it<50000) { essai(); } }  
 
ca plante par contre avec it < 500, ca marche.

n°661933
nraynaud
lol
Posté le 03-03-2004 à 12:43:33  profilanswer
 

quelle est la taille du tableau iPix ?
 
D'une manière générale, ce n'est *jamais* en raison de la taille des données mais en raison d'un bug qu'on a ce genre d'erreur. En particulier quand on a un code aussi dégueulasse.


---------------
trainoo.com, c'est fini
n°662157
droopy 76
Posté le 03-03-2004 à 15:06:03  profilanswer
 

ce n'est pas à mon avis en terme de taille de données mais plutôt d'itérations.

n°662563
BifaceMcLe​OD
The HighGlandeur
Posté le 04-03-2004 à 11:18:02  profilanswer
 

Par construction, la pile d'appels n'est pas infinie.
 
Pour confirmer/infirmer tes dires, j'ai fait un petit test rapide :

Code :
  1. public class StackOverflow {
  2.   public static void main(String[] args) {
  3.     StackOverflow  so = new StackOverflow();
  4.     try {
  5.       so.recursive();
  6.     }
  7.     catch (StackOverflowError e) {
  8.       System.err.println("StackOverflowError levée après " + so.numAppels + " appels." );
  9.     }
  10.   }
  11.   private int numAppels = 0;
  12.   public void recursive() {
  13.     this.numAppels++;
  14.     this.recursive();
  15.   }
  16. }


Et voici le résultat sur ma machine (avec Java HotSpot(TM) Client VM (build 1.3.1_09-b03, mixed mode) :

StackOverflowError levée après 17719 appels.


 
Ce qui confirme que la récursivité n'est pas faite pour des millers d'appels récursifs, seulement quelques dizaines ou quelques centaines. Au-delà, comme le dit nraynaud, il faut dérécursifier en utilisant sa propre pile.
 
Et au passage, factoriser ton code serait aussi une très bonne idée (ton double "if" existe en huit exemplaires !). Du genre :

Code :
  1. private void getPartImage(int cSel, int x, int y, int w, int h) {
  2.   for (int ii = -1; ii <= 1; ii++) {
  3.     for (int jj = -1; jj <= 1; jj++) {
  4.       if (ii != 0  &&  jj != 0) {
  5.         int  xx = x + ii;
  6.         int  yy = y + jj;
  7.         if (xx < w  &&  yy < h  &&  yy >=0  &&  xx >= 0) {
  8.           if (iPix[yy * w + xx] == cSel) {
  9.             iPix[yy * w + xx] = -255;
  10.             vPix.add(new Dimension(xx, yy));
  11.             this.getPartImage(cSel, xx, yy, w, h);
  12.           }
  13.         }
  14.       }
  15.     }
  16.   }
  17. }


 
Un tel code est déjà beaucoup plus lisible, beaucoup plus facile à maintenir que ton code initial (et pourtant, il est strictement équivalent pour la machine). Et il sera beaucoup plus facile à dérécursifier.

n°664836
droopy 76
Posté le 05-03-2004 à 21:35:37  profilanswer
 

rehello,
 
Je suis tous à fait d'accord avec toi BifaceMcLeOD. J'ai fait ce code en quelques minutes pour essayer de voir si ça fonctionnait.
Les performances de la machine ne sont d'ailleurs pas mise à contribution par rapport à un code plus propre. J'ai l'intention de coder proprement les méthodes.
Par contre, j'essaye de résoudre le pb technique ce qui m'énerve de + en +.
J'ai essayer sous forme d'applet un code équivalent un peu comme celui proposé précédemment et il n'y a pas de souci. Par contre, sous forme d'appli ca plante.
 
Il y a une exception levée pour les fonctions récursives trop longue. c la première fois que je trouve JAVA bizarre (ou c moi ???).
 
En tout cas j'apprécie ton discours constructifs. je pense que "Rien ne sert de coder proprement pour tester qqch à l'origine"
Par contre ensuite, il est clair que c plutot indispensable.

n°665035
benou
Posté le 06-03-2004 à 01:59:34  profilanswer
 

Une pile d'appel 17000 c'est déjà pas mal, hein [:kiki]

n°665038
nraynaud
lol
Posté le 06-03-2004 à 02:15:45  profilanswer
 

benou a écrit :

Une pile d'appel 17000 c'est déjà pas mal, hein [:kiki]

ça dépend de la taille des frames, hein [:kiki]
 
 
bon et le monsieur il va arrêter de croire que c'est de la faute du matériel s'il a touché le fond de la pile !


---------------
trainoo.com, c'est fini
n°665084
droopy 76
Posté le 06-03-2004 à 09:03:56  profilanswer
 

Le programme est fait pour récupérer des zones d'une image. La fonction récursive fonctionnera ou non selon la taille de l'image.
J'aimerai savoir s'il faut que je traite en plusieurs fois l'image selon sa taille s'il existe une autre solution.
 
Ceci dit je n'ai pas encore trouvé un outil du type photoshop qui permet de faire un remplissage d'une zone non régulière en JAVA.

mood
Publicité
Posté le 06-03-2004 à 09:03:56  profilanswer
 

n°665089
docmaboul
Posté le 06-03-2004 à 09:14:57  profilanswer
 

BifaceMcLeOD a écrit :


Ce qui confirme que la récursivité n'est pas faite pour des millers d'appels récursifs, seulement quelques dizaines ou quelques centaines.


 
De toute façon, il vaut mieux éviter au maximum d'écrire des fonctions récursives pour des raisons de performances ou sinon, de bien savoir ce que l'on fait. Souvent, cela revient à gaspiller sa cpu et d'autant plus que toute fonction récursive peut s'écrire avec un algo non-récursif.


Message édité par docmaboul le 06-03-2004 à 09:15:17
n°665091
droopy 76
Posté le 06-03-2004 à 09:19:02  profilanswer
 

DocMaboul a écrit :


 
De toute façon, il vaut mieux éviter au maximum d'écrire des fonctions récursives pour des raisons de performances ou sinon, de bien savoir ce que l'on fait. Souvent, cela revient à gaspiller sa cpu et d'autant plus que toute fonction récursive peut s'écrire avec un algo non-récursif.


 
merci de toutes vos remarques. Ca m'a fait pas mal avancé. Je vais ecrire une fonction avec des boucles imbriqués.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  exception StackOverflowError

 

Sujets relatifs
contrainte d'intégrité, triggers et exceptionSTL : gestion des exception. appel explicite?
Levée d'exception & singletonException in thread "main" org.omg.CORBA.COMM_FAILURE
Debogger, et suivi de trace d'exceptionGerer les exception avec JNI
Exception System.TypeLoadException Exception definie par l utilisateur sous ORACLE (+Delphi) [RESOLU]
la chaine de caractères dans std::exceptionOpenSCManager et exception mémoire
Plus de sujets relatifs à : exception StackOverflowError


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR