首页 > 解决方案 > 我的 CS50 模糊滤镜上的 UndefinedBehaviorSanitizer

问题描述

我似乎无法弄清楚为什么这个错误不断发生。我对编码相当陌生,该程序应该使用框模糊来模糊图像,但是当我尝试执行该程序时出现错误。我知道这可能不是最有效的解决方案,但任何关于如何让它工作的提示将不胜感激!

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE old[height][width];

    for(int i = 0; i < height; i++)
    {
        for(int j = 0; j < width; j++)
        {
            old[i][j] = image[i][j];
        }
    } 
    for(int i = 0; i < height; i++)
    {
        for(int j = 0; j < width; j++)
        {
            //top left corner
            if(j == 0 && i == 0)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed) /4);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen) /4);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue) /4);
            } 
            //top right corner
            else if(j == width && i == 0)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed) /4);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen) /4);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue) /4);
            } 
            //bottom left corner
            else if(j == 0 && i == height - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /4);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /4);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /4);
            } 
            //bottom right corner
            else if(j == width && i == height - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /4);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /4);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /4);
            } 
            //first row
            else if(i == 0 && j > 0 && j < width - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed) /6);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen) /6);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue) /6);
            }
            //last row
            else if(i == height && j > 0 && j < width - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i-1][j-1].rgbtRed) /6);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
            }
            //first column 
            else if(j == 0 && i > 0 && i < height - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j+1].rgbtRed) /6);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j+1].rgbtGreen) /6);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j+1].rgbtBlue) /6);
            }
            //last column
            else if(j == width && i > 0 && i < height - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed) /6);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen) /6);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue) /6);
            }
            else if(i < height - 1 && j < width - 1)
            {
                image[i][j].rgbtRed = round( (old[i][j].rgbtRed + old[i][j+1].rgbtRed + old[i+1][j].rgbtRed + old[i+1][j+1].rgbtRed + old[i][j-1].rgbtRed + old[i+1][j-1].rgbtRed + old[i-1][j].rgbtRed + old[i-1][j-1].rgbtRed + old[j-1][i+1].rgbtRed) /9);
                image[i][j].rgbtGreen = round( (old[i][j].rgbtGreen + old[i][j+1].rgbtGreen + old[i+1][j].rgbtGreen + old[i+1][j+1].rgbtGreen + old[i][j-1].rgbtGreen + old[i+1][j-1].rgbtGreen + old[i-1][j].rgbtGreen + old[i-1][j-1].rgbtGreen + old[j-1][i+1].rgbtGreen) /9);
                image[i][j].rgbtBlue = round( (old[i][j].rgbtBlue + old[i][j+1].rgbtBlue + old[i+1][j].rgbtBlue + old[i+1][j+1].rgbtBlue + old[i][j-1].rgbtBlue + old[i+1][j-1].rgbtBlue + old[i-1][j].rgbtBlue + old[i-1][j-1].rgbtBlue + old[j-1][i+1].rgbtBlue) /9);
            }
        }
    }
}
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==9889==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7fff298bd0b8 (pc 0x000000442a96 bp 0x7fff298bc2b0 sp 0x7fff298071c0 T9889)
==9889==The signal is caused by a READ memory access.
    #0 0x442a95  (/home/ubuntu/pset4/filter/filter+0x442a95)
    #1 0x4232f1  (/home/ubuntu/pset4/filter/filter+0x4232f1)
    #2 0x7f302ce5db96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #3 0x402e19  (/home/ubuntu/pset4/filter/filter+0x402e19)

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

标签: cundefined-behaviorcs50

解决方案


当您尝试对如此多的边缘情况(字面意思是呵呵)进行硬编码时,可能会出现问题。为什么不尝试矩阵遍历呢?即构造一个假想矩阵,以当前像素([i][j])为中心,现在遍历所述矩阵的所有有效像素并将它们相加。简单高效。

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{

    RGBTRIPLE old[height][width];
    for (int i = 0; i < height; i++)
    {
        // Copy the original image over to a temporary variable, row by row
        memcpy(old[i], image[i], sizeof(RGBTRIPLE) * width);
    }
    // Iterate through rows
    for (int i = 0; i < height; i++)
    {
        // Iterate through columns
        for (int j = 0, red, green, blue, count; j < width; j++)
        {
            // Reset the variables
            red = blue = green = count = 0;
            // Move row-wise in the imaginary matrix (centered around [i][j])
            for (int r = i - 1; r <= i + 1; r++)
            {
                // Move column-wise in the imaginary matrix (centered around [i][j])
                for (int c = j - 1; c <= j + 1; c++)
                {
                    // Check for invalid pixels
                    if (r < 0 || r > height - 1)
                    {
                        // Invalid row, no need to continue, move on to next row
                        break;
                    }
                    if (c > -1 && c < width)
                    {
                        // Valid pixel
                        count++;
                        // Sum up every pixel color
                        red += old[r][c].rgbtRed;
                        green += old[r][c].rgbtGreen;
                        blue += old[r][c].rgbtBlue;
                    }
                }
            }
            // Calculate the average and assign
            image[i][j].rgbtRed = round((float)red / count);
            image[i][j].rgbtGreen = round((float)green / count);
            image[i][j].rgbtBlue = round((float)blue / count);
        }
    }
    return;
}

除了通过在每个像素周围构造一个假想矩阵并检查所述矩阵的内部索引之外,这与您想要实现的目标相同- 我们使这个问题变得更加简单。


推荐阅读