A warning: do not read this post if you’re currently working on problem set 4 for cs50. Doing so would violate the course’s academic dishonesty policy.
I ran into an interesting bug while working on a c++ problem set for cs50. The function is supposed to flip a .bmp image horizontally. Here’s my first attempt:
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE *buffer = malloc(sizeof(buffer));
for (int i = 0; i <= height; i++)
{
for (int j = 0; j < width - j; j++)
{
*buffer = image[i][j];
image[i][j] = image[i][width - j];
image[i][width - j] = *buffer;
}
}
free(buffer);
return;
}
This worked…almost. Every column of pixels was replaced by its partner from the opposite side of the image except the first column. That one was simply moved up one pixel.
My hypothesis is that the argument width delivers the total number of columns of pixels, rather than a count of the columns starting with 0. Consequently, my function starts by trying to grab a pixel from beyond the last column.
This took me a minute to figure out because I would have thought that trying to reach beyond the last column would result in a segmentation error, but apparently it just wraps around to the beginning of the next row. That’s why my first column was simply moving up one pixel. What I found particularly interesting is that it doesn’t result in a segmentation error even from the last row, where it is reaching for a pixel from a row that doesn’t exist. It simply resulted in a black pixel.
In any case, the solution is straightforward: simply reduce the number of the column you’re reaching for by one.
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE *buffer = malloc(sizeof(buffer));
for (int i = 0; i <= height; i++)
{
for (int j = 0; j < width - j; j++)
{
*buffer = image[i][j];
image[i][j] = image[i][width - 1 - j];
image[i][width - 1 - j] = *buffer;
}
}
free(buffer);
return;
}