CS50 Week4 C语言BMP模糊函数触发segmentation fault排查
BMP模糊函数段错误排查
段错误根本原因
段错误由数组下标越界访问非法内存导致,出错位置为处理当前像素正下方邻点的分支:
if (i + 1 <= height - 1) { temp_red = temp_red + image[i-1][j].rgbtRed; temp_green = temp_green + image[i-1][j].rgbtGreen; temp_blue = temp_blue + image[i-1][j].rgbtBlue; counter++; }
该分支判断条件为「当前行的下一行存在有效像素」,逻辑上应该访问image[i+1][j](正下方像素),你错写为image[i-1][j]。当遍历到第一行(i=0)时,只要图像高度大于1,判断条件即成立,此时i-1 = -1,访问数组起始地址之前的未分配内存,直接触发段错误。
其他逻辑错误
除越界问题外,代码还有两处会导致计算结果完全错误的问题:
- 颜色累加临时变量
temp_red、temp_green、temp_blue定义在两层循环外部,处理完单个像素后没有重置为0,后续像素的累加值会叠加上之前的计算结果,平均值计算完全失真。将这三个变量移到内层j循环的开头即可,每次处理新像素时会自动初始化为0。 - 你创建了
copy数组存储模糊后的像素值,但函数结束前未将copy的内容拷贝回原image数组,计算结果不会实际生效。
修正后完整代码
#include <math.h> // Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE copy[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width ; j++) { float temp_red = 0, temp_green = 0, temp_blue = 0; int counter = 0; // 左上邻点 if (i >= 1 && j >= 1) { temp_red += image[i-1][j-1].rgbtRed; temp_green += image[i-1][j-1].rgbtGreen; temp_blue += image[i-1][j-1].rgbtBlue; counter++; } // 右上邻点 if (i >= 1 && j + 1 <= width - 1) { temp_red += image[i - 1][j + 1].rgbtRed; temp_green += image[i - 1][j + 1].rgbtGreen; temp_blue += image[i - 1][j + 1].rgbtBlue; counter++; } // 正上邻点 if (i >= 1) { temp_red += image[i-1][j].rgbtRed; temp_green += image[i-1][j].rgbtGreen; temp_blue += image[i-1][j].rgbtBlue; counter++; } // 正左邻点 if (j >= 1) { temp_red += image[i][j-1].rgbtRed; temp_green += image[i][j-1].rgbtGreen; temp_blue += image[i][j-1].rgbtBlue; counter++; } // 正右邻点 if (j + 1 <= width - 1) { temp_red += image[i][j+1].rgbtRed; temp_green += image[i][j+1].rgbtGreen; temp_blue += image[i][j+1].rgbtBlue; counter++; } // 左下邻点 if (i + 1 <= height - 1 && j >= 1) { temp_red += image[i+1][j-1].rgbtRed; temp_green += image[i+1][j-1].rgbtGreen; temp_blue += image[i+1][j-1].rgbtBlue; counter++; } // 正下邻点(修正之前的下标错误) if (i + 1 <= height - 1) { temp_red += image[i+1][j].rgbtRed; temp_green += image[i+1][j].rgbtGreen; temp_blue += image[i+1][j].rgbtBlue; counter++; } // 右下邻点 if (i + 1 <= height - 1 && j + 1 <= width - 1) { temp_red += image[i+1][j+1].rgbtRed; temp_green += image[i+1][j+1].rgbtGreen; temp_blue += image[i+1][j+1].rgbtBlue; counter++; } // 当前像素自身 temp_red += image[i][j].rgbtRed; temp_green += image[i][j].rgbtGreen; temp_blue += image[i][j].rgbtBlue; counter++; copy[i][j].rgbtRed = round(temp_red / counter); copy[i][j].rgbtGreen = round(temp_green / counter); copy[i][j].rgbtBlue = round(temp_blue / counter); } } // 将计算结果拷贝回原图像 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { image[i][j] = copy[i][j]; } } return; }
内容的提问来源于stack exchange,提问作者kenblitzer
相关产品推荐
相关产品推荐

