Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Переполнение стека


Автор: makartetsky 27.2.2008, 20:30
Привет. Такая тема. (Использую рекурсивный растровый алгоритм flood fill.) 
Код

private void Recurs(int x, int y)
      {
          
        if (Quasi.GetPixel(x,y).G > 0 && Quasi.GetPixel(x,y).R == 0 && Quasi.GetPixel(x,y).B == 0)
        { 
            if (Watch[x,y] == 0) Quasi.SetPixel(x,y,Color.Blue);
        }
        else  
        {
          if (x+1<400 && Watch[x+1,y] == 0)  Recurs(x+1,y);
          if (y + 1 < 400 && Watch[x, y+1] == 0) Recurs(x, y + 1);
          if (x - 1 > 0 && Watch[x-1, y] == 0) Recurs(x - 1, y);
          if (y - 1 > 0 && Watch[x, y-1] == 0) Recurs(x, y - 1);
        }
          Watch[x,y] = 1;
      }



На строке         if (Quasi.GetPixel(x,y).G > 0 && Quasi.GetPixel(x,y).R == 0 && Quasi.GetPixel(x,y).B == 0) происходит переполнение стека. Почему, не знаете? 

Автор: marcusmae 27.2.2008, 23:55
makartetsky, 

Вы используете рекурсию. По всей видимости, превышен максимальный уровень вложенности.

Цитата(makartetsky @  27.2.2008,  20:30 Найти цитируемый пост)
(Quasi.GetPixel(x,y).G > 0 && Quasi.GetPixel(x,y).R == 0 && Quasi.GetPixel(x,y).B == 0)

Не забыли ли Вы тут случайно скобки..?

А вообще с рекурсией надо аккуратнее. Рекурсивные алгоритмы конечно проще составить, но затем лучше преобразовывать в обычные - многие рекурсивные алгоритмы можно переписать без рекурсии.

Автор: makartetsky 28.2.2008, 00:00
Marcusmae, к сожалению, этот алгоритм относится к числу тех, которые нельзя переписать без рекурсии. 
Что касается скобок - то нет, вроде не забыл. 
Может можно как то увеличить размер стека?

Автор: marcusmae 28.2.2008, 00:13
Цитата(makartetsky @  28.2.2008,  00:00 Найти цитируемый пост)
Может можно как то увеличить размер стека?


Забудьте об этом.

Цитата(makartetsky @  28.2.2008,  00:00 Найти цитируемый пост)
Что касается скобок - то нет, вроде не забыл. 


Для начало давайте в этом убедимся. Если что, логическое && имеет больший приоритет, чем неравенства. То есть скобки могли бы стоять так :

Код

((Quasi.GetPixel(x,y).G > 0) && (Quasi.GetPixel(x,y).R == 0) && (Quasi.GetPixel(x,y).B == 0))


Нет?

Цитата(makartetsky @  28.2.2008,  00:00 Найти цитируемый пост)
к сожалению, этот алгоритм относится к числу тех, которые нельзя переписать без рекурсии


Дааа? = Что-то я в этом сильно сомневаюсь! Распространяющийся из точки крестик ... над этим лучше подумать завтра, но предполагаю, что всё же он развёртывается в прямые циклы. Но ессесно это будет слегка другой алгоритм.

Автор: makartetsky 28.2.2008, 00:37
smile
Насчет скобок. Всегда писал подобные условия без внутренних скобок - работало как надо. На досуге надо будет убедиться в этом путем побора примера. 

Цитата

Распространяющийся из точки крестик ... 


Прошу заметить, не просто распространяющийся из точки крестик, а крестик, обходящий контуры, присутствующие на рисунке.
 
А почему надо забыть про увеличение стека?

Автор: marcusmae 28.2.2008, 01:03
Цитата(makartetsky @  28.2.2008,  00:37 Найти цитируемый пост)
А почему надо забыть про увеличение стека?


Потому что не делают так. Вам никакого стека не хватит.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)