如何修复递归Flood Fill分段错误?

时间:2017-04-19 13:10:55

标签: c++ c sdl-2

嗨我正在制作一个简单的绘画程序来学习sdl和C,我在运行代码时遇到分段错误,我认为这是因为它试图填充窗外的像素,但是我我不知道如何阻止这种情况发生。 有没有办法阻止递归访问窗口外? 这是代码:对不起有多乱。

void floodfill(SDL_Surface *canvas,int SCREEN_WIDTH, int SCREEN_HEIGHT, int x, int y, int boundingX, int boundingY, Uint32 src, Uint32 fillcolour)
{

Uint32 clickedColour = getPixel(canvas, x, y);
Uint32 boundingColour = getPixel(canvas, boundingX, boundingY); //make sure you are not exceeding the limits of the window.

printf("floodfill Inside\n");
printf("X&Y co-ords %d,%d\n",x,y);

if (src==fillcolour)
    return;

if (x <= 0 || x <= SCREEN_WIDTH || y <= 0  || y <= SCREEN_HEIGHT)
{
    printf("saying things!\n");
    return;
}

printf("%d,%d\n",x,y);

if (fillcolour != clickedColour)
    putPixel(canvas, x, y, fillcolour);

if (clickedColour !=boundingColour)
    return;

if ((x>=0 && x<SCREEN_WIDTH) && (y>=0 && y<SCREEN_HEIGHT))
{
    putPixel(canvas, x, y, fillcolour);
    printf("put Pixel x=%d and y=%d\n", x, y);
}

floodfill(canvas,SCREEN_WIDTH, SCREEN_HEIGHT, x, y+1, x, y+2, src, fillcolour);
floodfill(canvas,SCREEN_WIDTH, SCREEN_HEIGHT, x, y, x+2, y, src, fillcolour);
floodfill(canvas,SCREEN_WIDTH, SCREEN_HEIGHT, x, y, x, y+2, src, fillcolour);
floodfill(canvas,SCREEN_WIDTH, SCREEN_HEIGHT, x+1, y, x+2, y, src, fillcolour);

}

2 个答案:

答案 0 :(得分:1)

我不熟悉SDL,但至少你的边界检查看起来不正确。使用递归的通用C / C ++泛洪测试算法实现可能如下所示:

// Dimentions for screen to paint, in this case 10x10 matrix
#define SCREEN_HEIGHT 10
#define SCREEN_WIDTH  10

void floodFillTest(int x, int y, int old_color, int new_color, int matrix[][SCREEN_HEIGHT])
{
    // Check boundaries
    if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT)
        return;

    // Check color to fill boundaries
    if (matrix[x][y] != old_color)
        return;

    // Replace old color at (x, y)
    matrix[x][y] = new_color;

    floodFillTest(x+1, y, old_color, new_color, matrix);  // Recur east
    floodFillTest(x-1, y, old_color, new_color, matrix);  // Recur west
    floodFillTest(x, y+1, old_color, new_color, matrix);  // Recur south
    floodFillTest(x, y-1, old_color, new_color, matrix);  // Recur north
}

答案 1 :(得分:0)

任何递归实现的泛洪填充都会因足够大的输入而发生段错误而崩溃:

它以深度优先的方式遍历像素,这意味着递归调用的数量与填充泛滥的区域的大小成线性关系。由于像素较小,相比之下堆栈帧较大,堆栈空间有限(通常约为单位数量的mebibytes),即使是小图像也会导致堆栈空间耗尽,并且崩溃的过程会出现段错误。

因此,您可以安全地避免这种情况的唯一方法是重新实现您的算法,以便它使用循环而不是递归调用。 有两种变体:

  1. 具有显式堆栈的深度优先算法的迭代实现。这允许更深入的递归&#34;因为显式堆栈的缓冲区可能比调用堆栈大,并且通常会为每个递归级别将更少的数据压入堆栈。

  2. 使用广度优先算法。这可能更节省空间,因为在图像上移动的正面往往会更小。