0
votes

Qu'est-ce qui cause l'empilementflow? Et comment puis-je le résoudre?

Je faisais les devoirs pour des graphiques informatiques. Nous devons utiliser inondation code> pour peindre une zone, mais peu importe la façon dont j'ai changé la pile de réserve code> de Visual Studio, il sauterait toujours Stackoverflow code> .

void Polygon_FloodFill(HDC hdc, int x0, int y0, int fillColor, int borderColor) {
int interiorColor;
interiorColor = GetPixel(hdc, x0, y0);
if ((interiorColor != borderColor) && (interiorColor != fillColor)) {
    SetPixel(hdc, x0, y0, fillColor);
    Polygon_FloodFill(hdc, x0 + 1, y0, fillColor, borderColor);
    Polygon_FloodFill(hdc, x0, y0 + 1, fillColor, borderColor);
    Polygon_FloodFill(hdc, x0 - 1 ,y0, fillColor, borderColor);
    Polygon_FloodFill(hdc, x0, y0 - 1, fillColor, borderColor);
}


1 commentaires

Je ne connais pas la question, mais le titre résonne


3 Réponses :


1
votes

Vous pouvez avoir une zone trop grande à remplir, ce qui provoque des appels récursifs pour consommer toute la pile d'exécution de votre programme.

Vos options:

  • Cultiver encore plus la pile d'exécution, si vous pouvez
  • Réduisez la zone (qu'en est-il seulement 100x100 ou 20x20?)
  • Arrêtez d'utiliser la pile d'exécution et utilisez une structure de données qui fonctionne de la même manière, mais peut contenir plus d'éléments (en étant plus efficaces et / ou être capables de croître / être plus grand)
  • Utilisez un algorithme différent (par exemple, envisagez de partir de pixels individuels aux allures horizontales des pixels, il y aura beaucoup moins de ce dernier que l'ancien)

0 commentaires

0
votes

Qu'est-ce qui provoque l'empilement? p>

Quelle est la plage de x0 code>? +/- 2 000 000 000 000? C'est votre potentiel de profondeur de pile. P>

code n'empêche pas évidemment de sortir hors de portée sauf si getpixel (hors de portée) code> renvoie une valeur sans correspondance. P>

Et comment puis-je le résoudre? p> blockQuote>

Le code doit être plus sélectif sur les appels récursifs.
Quand une rangée de pixels peut être réglée, faites-le sans récursion.
Ensuite, examinez ensuite les voisins de la ligne et ne recueillent que lorsque les voisins n'avaient pas besoin de régler. P>

Une approche prometteuse gérerait le milieu puis regardait les 4 directions cardinales. P>

// Pseudo code
Polygon_FloodFill(x,y,c)
  if (pixel(x,y) needs filling) {    
    set pixel(x,y,c);
    for each of the 4 directions 
      // example: east
      i = 1; 
      // fill the east line first  
      while (pixel(x+i,y) needs filling) {     
        i++;
        set pixel(x,y,c);
      }
      // now examine the line above the "east" line
      recursed = false;
      for (j=1; j<i; j++) {
        if (pixel(x+j, y+j) needs filling) {     
          if (!recursed) {
            recursed = true;
            Polygon_FloodFill(x+j,y+j,c)
          } else  {
            // no need to call Polygon_FloodFill as will be caught with previous call
          }
        } else {
          recursed = false;
        }
      }
      // Same for line below the "east" line

      // do same for south, west, north.
    }


0 commentaires

0
votes

Combien de pixels à remplir? Chaque pixel est un niveau en profondeur de récursion et vous avez beaucoup de variables de toutes les variables locales et opérandes de la fonction récursive + la valeur de retour et l'adresse de retour pour atteindre le pixel que vous stockez:

HDC floodfill_hdc;
int floodfill_x0,floodfill_y0,floodfill_fillColor,floodfill_borderColor;
void _Polygon_FloodFill()
 {
 // here your original filling code
 int interiorColor;
 ...
 }
void PolygonFloodFill(HDC hdc, int x0, int y0, int fillColor, int borderColor) // this is what you call when want to fill something
 {
 floodfill_hdc=hdc;
 floodfill_x0=x0;
 floodfill_y0=y0;
 floodfill_fillColor=fillColor;
 floodfill_borderColor=borderColor;
 _Polygon_FloodFill();
 }


0 commentaires