0
// A part of Code
 int dim1=height;
 int dim2=width;
 int dim3=3;
    
 int k;
 
  unsigned char *** image = (unsigned char  ***)malloc(dim1*dim2*3);

        for (i = 0; i< dim1; i++) {

             image[i] = (unsigned char  **)malloc(dim2*sizeof(unsigned char  *));

          for (j = 0; j < dim2; j++) {

              image[i][j] = (unsigned char  *)malloc(dim3*sizeof(unsigned char ));
          }

        }




// B part of Code
  for (i = 0; i < height; i++) {
        
           for (j = 0; j < width; j++) {
               
                   
        fread(&image[i][j][0],sizeof(unsigned char),1,fp);
        fread(&image[i][j][1],sizeof(unsigned char),1,fp);
        fread(&image[i][j][2],sizeof(unsigned char),1,fp);
         
          
                   
         
           }
        
    }

As you can see from above I am trying to declare a 3d array that will contain the pixel information of a bmp image. The fp pointer is to a binary file that the data is contained there.

My question is how is it possible when I try to fread using dynamic memory allocation to get wrong results in image table (meaning a blank image is printed even though the rest of my code that i dont include here is correct). On the other hand when i remove the A part of the Code and replace it with "unsigned char image[height][width][3]" it works.

So what am i doing wrong in the memory allocation or in the use of fread? Because obviously the problem is there.

In order to make it easier lets assume that the size is 252x252x3.

  • Remember that the size passed to the `malloc` function is the amoutn of *bytes* to allocate, not the number of "elements" (since the `malloc` function just can't know anything about that). So `malloc(dim1*dim2*3)` doesn't make much sense. Especially since you later do more allocations so it should probably be `malloc(dim1 * sizeof *image)` – Some programmer dude Jul 17 '21 at 16:08
  • You are right, i tried but still not correct. By the way lets assume that the size of image is 252x252x3. – Petros Sofianos Jul 17 '21 at 16:25
  • You're not allocating a 3-d array. You're allocating multiple 1-d arrays of `char` that are referred to by multiple 1-d arrays of `char *` that are referred to by a single array of `char **`. If your compiler isn't stuck in the last century (hello MSVC...), you can use VLAs to allocate a true 3-d array with dynamic size. See [**Correctly allocating multi-dimensional arrays**](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Andrew Henle Jul 17 '21 at 16:32
  • So in my case how the declaration would be ? Cause i get segmentation fault with VLA's. – Petros Sofianos Jul 17 '21 at 16:45
  • The segmentation fault disappeared but still i dont get correct results. – Petros Sofianos Jul 17 '21 at 17:08
  • "contain the pixel information of a bmp image." --> note that each row of pixel data might have a multiple of 4 requirement, necessitating some padding bytes. – chux - Reinstate Monica Jul 18 '21 at 01:49

1 Answers1

1
typedef struct
{
    unsigned char R;
    unsigned char G;
    unsigned char B;
}RGB;

void *allocateReadImage(size_t width, size_t height, FILE *fi)
{
    RGB (*picture)[width] = malloc(sizeof(*picture) * height);

    if(picture && fi)
    {
        if(fread(picture, sizeof(*picture), height, fi) != height)
        {
            free(picture);
            picture = NULL;
        }
    }
    return picture; 
}

usage:

RGB *mypicture = allocateReadImage(1600, 1200, inputfile);
if(!mypicture) { /*some error handling*/ }
0___________
  • 60,014
  • 4
  • 34
  • 74