Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm attempting to create an 8x8 checkerboard PGM in C

Tags:

c

Hello I attempting to write a C program that creates an 800x800 pixel PGM file and then populates the file with 100x100 pixel alternating black and white squares. It compiles fine, freezes when executing, and the resulting PGM file appears to only be a thin alternating black and white line.

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char* argv[])
{
    /*Declaring variables for rows, columns, boardsize, squaresize and pgmData 
    array*/
    int row, col,i,j;
    int iBoardSize = 800, iSquareSize = 100;
    int **iPgmData;

    /*Allocate memory for the data*/
    row = 800;
    col = 800;

    iPgmData = malloc(row * sizeof(int *));
    for (i = 0; i < row;i++)
        iPgmData[i] = malloc(col * sizeof(int));

    /*Assign data to the array the desired result is an 8x8 checkboard of 100x100
    pixel squares of alternating black and white.*/
    for (row = 0; row < iBoardSize; row++){
        for (col = 0; col < iBoardSize; col++){
            if ((row / iSquareSize + col / iSquareSize ) %2 == 0)
                iPgmData[row][col] = 0;
            else
                iPgmData[row][col] = 255;

        }
    }

    /* Open the PGM file */
    FILE* image = fopen(argv[1], "wb");
    if (image == NULL){
      fprintf(stderr, "Can't open output file %s!\n", argv[1]);
      exit(1);
    }

    /*Write the header*/
    fprintf(image, "P2\n%d %d\n255\n", iBoardSize, iBoardSize);

    for (row = 0;row <= iBoardSize; row++){
        for (col = 0;col <= iBoardSize; col++){
            if (col < iBoardSize)
                fprintf(image, "%d ", iPgmData[row][col]);
            else
                fprintf(image, "\n");
        }
    }

    /*Write pgmData*/
    fwrite(iPgmData, 1, iBoardSize*iBoardSize*sizeof(int *), image);

    /*Close the PGM*/
    fclose(image);

    /*Free allocated memory*/
    free(iPgmData);

    return 0;
}
like image 682
Blair McKinney Avatar asked Feb 07 '23 20:02

Blair McKinney


1 Answers

Problems I see:

Using out of bounds array index

for (row = 0;row <= iBoardSize; row++){
             ^^^^^^^^^^^^^^^^ Wrong. Should be row < iBoardSize
   for (col = 0;col <= iBoardSize; col++){
                ^^^^^^^^^^^^^^^^ Wrong. Should be col < iBoardSize
      if (col < iBoardSize)
         fprintf(image, "%d ", iPgmData[row][col]);
      else
         fprintf(image, "\n");
   }
}

That block can be simplified to:

for (row = 0;row < iBoardSize; row++){
   for (col = 0;col < iBoardSize; col++){
      fprintf(image, "%d ", iPgmData[row][col]);
   }
   fprintf(image, "\n");
}

Call to fwrite

fwrite(iPgmData, 1, iBoardSize*iBoardSize*sizeof(int *), image);

You can use fwrite only if you have contiguous data. In your case, you don't. It's not clear to me what you hoped to accomplish from that call. I removed the call and the output file is a valid PGM file.

Not freeing the allocated memory correctly

You have

free(iPgmData);

That only deallocates the memory allocated for the pointers. It does not deallocated the memory the pointers point to. You need to use:

for (i = 0; i < row;i++)
   free(iPgmData[i]);

free(iPgmData);
like image 190
R Sahu Avatar answered Feb 16 '23 02:02

R Sahu