Abraham Lincoln Abraham Lincoln - 1 month ago 19
C Question

Structures in C

I've faced with a problem in PSET4 (whodunit). I really don't understand why errors occure in the next case below, although compile doesn't make a warning.

In this problem I should read each pixel of given .bmp file, substitute each red pixel by white pixel and write new image in a new .bmp file.

Here are 2 versions of my code. In the first listing there is a correct version of code, and program works correctly as I wanted. In the second listing there is an example of code, that successfully compiled, but pixels either still the same, or happens smth strange.

CORRECT VERSION

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{ //CORRECT VERSION
// temporary storage
RGBTRIPLE triple;

// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
if((triple.rgbtRed == 0xff) && (triple.rgbtGreen == 0x00) && (triple.rgbtBlue == 0x00))
{
triple.rgbtBlue = 0xff;
triple.rgbtGreen = 0xff;
triple.rgbtRed = 0xff;
}

// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}


INCORRECT VERSION

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{ //INCORRECT VERSION
// temporary storage
RGBTRIPLE triple[i][j];

// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
if((triple[i][j].rgbtRed == 0xff) && (triple[i][j].rgbtGreen == 0x00) && (triple[i][j].rgbtBlue == 0x00))
{
triple[i][j].rgbtBlue = 0xff;
triple[i][j].rgbtGreen = 0xff;
triple[i][j].rgbtRed = 0xff;
}

// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}


According to the "arrays" lessons (and to example with "students" structure in CS50), it is required thing to include indexes [i] and [j] for the arrays and structs variables during "for"-loop executing. But in this case everything's getting invalid, if I put those indexes in the code. And everything is OK if I do not write those indexes. Why does this logic break here, with structures?

Answer

When you declare RGBTRIPLE triple[i][j]; you make a 2D array with valud indexes 0..i-1 and 0..j-1. Accessing triple[i][j] is undefined behavior; that's why your second solution fails.

However, you do not need a whole array of RGBTRIPLE, because you process them one at a time. That is why your first solution works.

If you need to read the whole array, declare it before the outer loop with correct dimensions:

RGBTRIPLE triple[abs(bi.biHeight)][abs(bi.biWidth)];

Be careful with this solution, because you may cause a crash for very large values of bi.biHeight*bi.biWidth.