I have been working on Problem Set 4 of CS50 and have finally completed Filters. However, while my program passes check50, when I try to run ./filter -e images/courtyard.bmp out.bmp
I will get this scary-looking error:
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
I tried to use help50 but it didn't help, and my code works fine with all the other functions (grayscale
, reflection
, blur
). Here is my code for 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;
}
I have no idea why this is happening. Please help me diagnose this problem! Thanks.
Barmar's comment, that image[x + a][y + b]
will access outside the array when x = 0
and a = -1
, told me specifically where the error was. I was able to find my problem, which is that one of my if-statements was missing a continue
, so the code that wasn't meant to execute for a specific case would end up being run anyway. The correct code should have been
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;
}
instead of
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;
}
}