如何处理 C 中的未定义行为错误?

What to do about Undefined Behavior error in C?

我一直在研究 CS50 的第 4 题,终于完成了过滤器。然而,当我的程序通过 check50 时,当我尝试 运行 ./filter -e images/courtyard.bmp out.bmp 时,我会得到这个看起来很可怕的错误:

UndefinedBehaviorSanitizer:DEADLYSIGNAL
==3887==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7f5cd508e90a (pc 0x00000042ba94 bp 0x7fffa080dcc0 sp 0x7fffa075c560 T3887)
==3887==The signal is caused by a READ memory access.
    #0 0x42ba93  (/home/ubuntu/pset4/filter/filter+0x42ba93)
    #1 0x42339e  (/home/ubuntu/pset4/filter/filter+0x42339e)
    #2 0x7f5cd3f81b96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #3 0x402ea9  (/home/ubuntu/pset4/filter/filter+0x402ea9)

UndefinedBehaviorSanitizer can not provide additional info.
==3887==ABORTING

我尝试使用 help50 但没有用,而且我的代码与所有其他函数(grayscalereflectionblur)一起工作正常。这是我的 edges:

代码
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE edgy[height][width];

    int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    int gx_red[3][3];
    int gy_red[3][3];
    int gx_blue[3][3];
    int gy_blue[3][3];
    int gx_green[3][3];
    int gy_green[3][3];

    int redx;
    int redy;
    int bluex;
    int bluey;
    int greenx;
    int greeny;

    for (int x = 0; x < height; x++)
    {
        for (int y = 0; y < width; y++)
        {
            for (int e = 0; e < 3; e++)
            {
                for (int f = 0; f < 3; f++)
                {
                    gx_red[e][f] = gx[e][f];
                    gy_red[e][f] = gy[e][f];
                    gx_blue[e][f] = gx[e][f];
                    gy_blue[e][f] = gy[e][f];
                    gx_green[e][f] = gx[e][f];
                    gy_green[e][f] = gy[e][f];
                }
            }

            redx = 0;
            redy = 0;
            bluex = 0;
            bluey = 0;
            greenx = 0;
            greeny = 0;


            for (int a = -1; a < 2; a++)
            {
                if ((x + a < 0) || (x + a > height - 1))
                {
                    for (int z = 0; z < 3; z++)
                    {
                        gx_red[a + 1][z] *= 0;
                        gy_red[a + 1][z] *= 0;
                        gx_blue[a + 1][z] *= 0;
                        gy_blue[a + 1][z] *= 0;
                        gx_green[a + 1][z] *= 0;
                        gy_green[a + 1][z] *= 0;
                    }

                }
                for (int b = -1; b < 2; b++)
                {
                    if ((y + b < 0) || (y + b > width - 1))
                    {
                        for (int q = 0; q < 3; q++)
                        {
                            gx_red[q][b + 1] *= 0;
                            gy_red[q][b + 1] *= 0;
                            gx_blue[q][b + 1] *= 0;
                            gy_blue[q][b + 1] *= 0;
                            gx_green[q][b + 1] *= 0;
                            gy_green[q][b + 1] *= 0;
                        }
                    }
                    else
                    {
                        gx_red[a + 1][b + 1] *= image[x + a][y + b].rgbtRed;
                        gy_red[a + 1][b + 1] *= image[x + a][y + b].rgbtRed;
                        gx_blue[a + 1][b + 1] *= image[x + a][y + b].rgbtBlue;
                        gy_blue[a + 1][b + 1] *= image[x + a][y + b].rgbtBlue;
                        gx_green[a + 1][b + 1] *= image[x + a][y + b].rgbtGreen;
                        gy_green[a + 1][b + 1] *= image[x + a][y + b].rgbtGreen;
                    }
                }
            }

            for (int a = 0; a < 3; a++)
            {
                for (int b = 0; b < 3; b++)
                {
                    redx += gx_red[a][b];
                    redy += gy_red[a][b];
                    bluex += gx_blue[a][b];
                    bluey += gy_blue[a][b];
                    greenx += gx_green[a][b];
                    greeny += gy_green[a][b];
                }
            }

            int final[3] = {round(sqrt(pow(redx, 2) + pow(redy, 2))),
                            round(sqrt(pow(bluex, 2) + pow(bluey, 2))),
                            round(sqrt(pow(greenx, 2) + pow(greeny, 2)))
                           };

            for (int i = 0; i < 3; i++)
            {
                if (final[i] > 255)
                {
                    final[i] = 255;
                }
                else if (final[i] < 0)
                {
                    final[i] = 0;
                }
            }

            edgy[x][y].rgbtRed = final[0];
            edgy[x][y].rgbtBlue = final[1];
            edgy[x][y].rgbtGreen = final[2];
        }
    }

    for (int x = 0; x < height; x++)
    {
        for (int y = 0; y < width; y++)
        {
            image[x][y].rgbtRed = edgy[x][y].rgbtRed;
            image[x][y].rgbtBlue = edgy[x][y].rgbtBlue;
            image[x][y].rgbtGreen = edgy[x][y].rgbtGreen;
        }
    }

    return;
}

我不知道为什么会这样。请帮我诊断这个问题!谢谢。

Barmar 的评论,image[x + a][y + b] 将在 x = 0a = -1 时访问数组外部,具体告诉我错误在哪里。我能够找到我的问题,那就是我的一个 if 语句缺少 continue,因此不打算针对特定情况执行的代码最终会变成 运行 .正确的代码应该是

            if ((x + a < 0) || (x + a > height - 1))
                {
                    for (int z = 0; z < 3; z++)
                    {
                        gx_red[a + 1][z] *= 0;
                        gy_red[a + 1][z] *= 0;
                        gx_blue[a + 1][z] *= 0;
                        gy_blue[a + 1][z] *= 0;
                        gx_green[a + 1][z] *= 0;
                        gy_green[a + 1][z] *= 0;
                    }
                    continue;
                }

而不是

            if ((x + a < 0) || (x + a > height - 1))
                {
                    for (int z = 0; z < 3; z++)
                    {
                        gx_red[a + 1][z] *= 0;
                        gy_red[a + 1][z] *= 0;
                        gx_blue[a + 1][z] *= 0;
                        gy_blue[a + 1][z] *= 0;
                        gx_green[a + 1][z] *= 0;
                        gy_green[a + 1][z] *= 0;
                    }
                }