CS50图像翻转函数reflect代码测试异常求助:像素偏移与首行零值
CS50 Reflect图像翻转函数的bug修复
你的问题核心是数组索引越界,导致访问了未初始化的内存区域(表现为零值)。
问题根源分析
看你代码里的这行关键代码:
reflected[h][w] = image[h][width - w];
因为图像数组的列索引范围是0到width-1,当w=0时,width - w = width,这个索引超出了数组的合法边界,访问到的是数组外的内存(通常是零值或垃圾数据)。
拿1x3的测试用例举例:
- 合法列索引是0、1、2
- w=0时你取的是
image[h][3](越界),得到零值 - w=1时取
image[h][2],w=2时取image[h][1] - 最终生成的reflected行是
[0, 0 0 255, 0 255 0],和预期完全错位
3x3测试用例的问题同理,每一行的第一个元素都是越界访问得到的零值。
修复后的代码
只需要把索引计算改成width - 1 - w,确保访问的是合法的数组元素:
void reflect(int height, int width, RGBTRIPLE image[height][width]) { RGBTRIPLE reflected[height][width]; for (int h = 0 ; h < height ; h++) { for (int w = 0 ; w < width ; w++) { // 修正索引:从width-1开始倒序取元素 reflected[h][w] = image[h][width - 1 - w]; } } // 复制回原图像 for (int h = 0 ; h < height ; h++) { for (int w = 0 ; w < width ; w++) { image[h][w] = reflected[h][w]; } } return; }
验证测试用例
- 1x3图像:w=0取
image[h][2],w=1取image[h][1],w=2取image[h][0],得到的reflected行就是[0 0 255, 0 255 0, 255 0 0],完全符合预期。 - 3x3图像:每一行的元素都会正确取到对应列的倒序值,不会再出现首行零值的问题。
另外可以优化代码,不需要额外创建reflected数组,直接在原数组上交换左右对称的元素(只遍历每一行的前半部分,和后半部分元素交换),更节省内存:
void reflect(int height, int width, RGBTRIPLE image[height][width]) { for (int h = 0; h < height; h++) { // 遍历每一行的左半部分 for (int w = 0; w < width / 2; w++) { // 交换当前元素和对称位置的元素 RGBTRIPLE temp = image[h][w]; image[h][w] = image[h][width - 1 - w]; image[h][width - 1 - w] = temp; } } return; }
内容的提问来源于stack exchange,提问作者Ahmed Hesham
相关产品推荐
相关产品推荐

