I got this error when I tried to look particular value exist or not. I used a custom data type called RGBTRIPLE
that cs50 provides me. If the value is not exist in the memory I will get 'segmentation fault' because I need to find out top left, top middle, top right, value that I have its previous value and next value, bottom left, bottom middle, bottom right value. So for that I used a function called isNull
. It will check whether the value exists in the memory or not. If it is not null It will return 1, otherwise 0.
Here is my code
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// entering the array of the image
for (int i = 0; i < height; i )
{
// entering the array of the row
for (int j = 0; j < width; j )
{
/* blur: the element we select we need to get the value
of its neighbour value and adding this all including it
then get the avg value of pixel that need to set
*/
int element = 0;
int blueSum = 0;
int greenSum = 0;
int redSum = 0;
RGBTRIPLE pixels[] = {
image[i][j], image[i][j - 1], image[i][j 1],
image[i - 1][j - 1], image[i - 1][j], image[i - 1][i 1],
image[i 1][j - 1], image[i 1][j], image[i 1][j 1]
};
for (int k = 0; k < 9; k )
{
if (isNull(pixels[k]) == 1)
{
element ;
blueSum = pixels[k].rgbtBlue;
greenSum = pixels[k].rgbtGreen;
redSum = pixels[k].rgbtRed;
}
}
image[i][j].rgbtBlue = round(blueSum / element);
image[i][j].rgbtGreen = round(greenSum / element);
image[i][j].rgbtRed = round(redSum / element);
}
}
return;
}
// check whether it is null or not
int isNull(RGBTRIPLE pixel)
{
if (pixel != 0)
{
return 1;
}
return 0;
}
Error I got:
$ make filter
helpers.c:142:15: error: invalid operands to binary expression ('RGBTRIPLE' and 'int')
if (pixel != 0)
~~~~~ ^ ~
1 error generated.
make: *** [Makefile:2: filter] Error 1
CodePudding user response:
the type RGBTRIPLE
is defined in bmp.h as:
/**
* RGBTRIPLE
*
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*
* Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
*/
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
It is a structure: you cannot compare structures with the ==
operator, you must compare members individually.
The problem is: what do you mean by check whether it is null or not?
If you mean "is the pixel black?", you should test if all 3 components are 0
:
// check whether it is black or not
int isBlack(RGBTRIPLE pixel) {
return ((pixel.rgbtBlue | pixel.rgbtGreen | pixel.rgbtRed) == 0);
}
You get a segmentation fault because you read pixels beyond the boundaries of the matrix image
:
- the 6th initializer
image[i - 1][i 1]
has a typo - you must make special cases for the image boundaries (
i == 0
,j == 0
,i == height - 1
andj == width - 1
).
Here is a simple fix:
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a < b ? b : a; }
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// entering the array of the image
for (int i = 0; i < height; i ) {
// entering the array of the row
for (int j = 0; j < width; j ) {
/* blur: compute the new color by averaging the components
of all pixels in a 3x3 area around the pixel.
assume that pixel colors continue beyond the image
borders.
*/
unsigned blueSum = 0;
unsigned greenSum = 0;
unsigned redSum = 0;
int i1 = max(0, i - 1);
int i2 = min(height - 1, i 1);
int j1 = max(0, j - 1);
int j2 = min(width - 1, j 1);
RGBTRIPLE pixels[] = {
image[i][j1], image[i][j], image[i][j2],
image[i1][j1], image[i1][j], image[i1][j2],
image[i2][j1], image[i2][j], image[i2][j2]
};
for (int k = 0; k < 9; k ) {
blueSum = pixels[k].rgbtBlue;
greenSum = pixels[k].rgbtGreen;
redSum = pixels[k].rgbtRed;
}
image[i][j].rgbtBlue = round(blueSum / 9);
image[i][j].rgbtGreen = round(greenSum / 9);
image[i][j].rgbtRed = round(redSum / 9);
}
}
}
Note however that the above function cannot work as coded because it overwrites the pixel values that will be used for the next column and for the next row. To perform this transformation in place, you can use a 2 line buffer to keep the previous values.
CodePudding user response:
You cannot compare scalar types with a struct or an array. That is what the error message is telling you.
What condition should be true to make a struct of multiple unrelated bytes to compare with a numerical value? That's not how it works. You can only compare the fields separately or compare whole struct with another variable of same struct type.
Besides that, you have a few misconceptions in your code.
If the value is not exist in the memory I will get 'segmentation fault'
You got a segmentation fault because the memory you want to read is not your memory. You have no access privileges to read or write.
It will check whether the value exists in the memory or not.
If you provide some value to a function, it will always "exist in memory". You have provided a value in the calling function. How would it not exist? You cannot detect if the memory location where you copied it from was valid by just looking at the copied value.
Your underlying problem is that you do not verify that you are withing bounds of your array before reading the values. You must compare row and column index with the limits and only access the array element if you are not out of bounds.
You need to rework your approach to collect pixels to blur.