Thursday, June 27, 2019

struct - Casting errors in malloc for "char" array in C language




Code to read bmp image using struct variables and struct array.
Kindly suggest me correct way to do typecasting to malloc(errors listed below code):



#include
#include

typedef struct bands{
/* .bmp image store pixel colors in "bgr" sequence */
unsigned char b,g,r; //in 24bit bmp, we need to use 8bit datatype for each color
}bands;

int main()
{
FILE *bmpimage; //ptr to read image file
FILE *redpix,*greenpix,*bluepix; //ptr to create band/color wise file
unsigned short pix_x=223,pix_y=197; /*pix_x: no. of pixels in a row, pix_y: no. of pixels in a column of input image*/
unsigned short n_pix=pix_x*pix_y; /*variable to count total no. of pixels*/

bmpimage=fopen("blocks223x197.bmp","r"); //24 bit bmpimage
redpix=fopen("redpixels.txt","w");
greenpix=fopen("greenpixels.txt","w");
bluepix=fopen("bluepixels.txt","w");

/* Define a pointer to a memory block,'*readbuffer',
that has 'n_pix' no. of memory blocks each of size same as struct bands */
bands *readbuffer=(char*)malloc(n_pix*sizeof(*readbuffer));

int n;
//Create memory for each of 'n_pix' no. of pixel array of each color
for(n=0;n unsigned char *readbuffer[n].b = (char*) malloc(sizeof(readbuffer[n].b));
unsigned char *readbuffer[n].g = (char*) malloc(sizeof(readbuffer[n].g));
unsigned char *readbuffer[n].r = (char*) malloc(sizeof(readbuffer[n].r));
}

if(!bmpimage){printf("Error reading bmpimage!");return 1;}
if(readbuffer==NULL){printf("NULL buffer"); exit(1);}

/* Go to 54th byte to access pixelvalue data (since, 24bit bmp format) */
fseek(bmpimage,54,SEEK_SET);

/* Read 'n_pix' no. of 'bgr' blocks each of which are of the size same as "struct bands" */
fread(readbuffer,sizeof(bands),n_pix,bmpimage); /*read 'n_pix' no. of 'bgr' blocks each of which are of the size same as "struct bands" to the memory address, 'readbuffer' or '&readbuffer[0]' */

int n_blocks=(sizeof(readbuffer)/sizeof(bands));
printf("no. of blocks read= %d, n_pix=%d",n_blocks,n_pix);


int i,j; int count; count=0;
/* logic to print pixel values in correct order*/

for(i=pix_y;i>0;i--){ /*for accessing row data. Choose to print from bottom to top*/
for(j=1;j<=pix_x;j++){ /*for accessing column data. Print from left to right*/

if(j!=pix_x){
fprintf(redpix,"%d,",readbuffer[(i-1)*pix_x + j].r);
fprintf(greenpix,"%d,",readbuffer[(i-1)*pix_x + j].g);
fprintf(bluepix,"%d,",readbuffer[(i-1)*pix_x + j].b);
}
else{
count++;
fprintf(redpix,"%d\n",readbuffer[(i-1)*pix_x + j].r);
fprintf(greenpix,"%d\n",readbuffer[(i-1)*pix_x + j].g);
fprintf(bluepix,"%d\n",readbuffer[(i-1)*pix_x + j].b);
}
}
}

// free allocated memory
for(n=0;n free(readbuffer[n].b) ;
free(readbuffer[n].g) ;
free(readbuffer[n].r) ;
}


fclose(bmpimage);fclose(redpix);fclose(bluepix);fclose(greenpix);

return 0;

}


References:
How to properly malloc for array of struct in C



malloc an array of struct pointers vs array of structs



List of errors:




bmpread_check.c: In function 'main':
bmpread_check.c:24:19: warning: initialization from incompatible pointer type >[enabled by default]
bands readbuffer=(char)malloc(n_pix*sizeof(*readbuffer));
^
bmpread_check.c:29:33: error: expected '=', ',', ';', 'asm' or 'attribute' >before '.' token
unsigned char readbuffer[n].b = (char)malloc(sizeof(readbuffer[n].b));
^
bmpread_check.c:29:33: error: expected expression before '.' token
bmpread_check.c:30:33: error: expected '=', ',', ';', 'asm' or 'attribute' >before '.' token
unsigned char readbuffer[n].g = (char)malloc(sizeof(readbuffer[n].g));
^
bmpread_check.c:30:33: error: expected expression before '.' token
bmpread_check.c:31:33: error: expected '=', ',', ';', 'asm' or 'attribute' >before '.' token
unsigned char readbuffer[n].r = (char)malloc(sizeof(readbuffer[n].r));
^
bmpread_check.c:31:33: error: expected expression before '.' token
bmpread_check.c:69:5: warning: passing argument 1 of 'free' makes pointer from >integer without a cast [enabled by default]
free(readbuffer[n].b) ;
^
In file included from bmpread_check.c:3:0:
c:\mingw\include\stdlib.h:357:38: note: expected 'void ' but argument is of >type 'unsigned char'
_CRTIMP void __cdecl __MINGW_NOTHROW free (void
);
^
bmpread_check.c:70:5: warning: passing argument 1 of 'free' makes pointer from >integer without a cast [enabled by default]
free(readbuffer[n].g) ;
^
In file included from bmpread_check.c:3:0:
c:\mingw\include\stdlib.h:357:38: note: expected 'void ' but argument is of >type 'unsigned char' _CRTIMP void __cdecl __MINGW_NOTHROW free (void);
^
bmpread_check.c:71:5: warning: passing argument 1 of 'free' makes pointer from >integer without a cast [enabled by default]
free(readbuffer[n].r) ;
^
In file included from bmpread_check.c:3:0:
c:\mingw\include\stdlib.h:357:38: note: expected 'void ' but argument is of type >'unsigned char'
_CRTIMP void __cdecl __MINGW_NOTHROW free (void
);
^



Answer



This:



bands *readbuffer=(bands*)malloc(n_pix*sizeof(bands));


(Note: not *readbuffer. It's bands)



has already allocated memory for all n_pix bands.



There is no need to allocate memory for b, g, r as they are not pointers.



So,



//Create memory for each of 'n_pix' no. of pixel array of each color 
// And allocating using for loop


is not needed.


No comments:

Post a Comment

plot explanation - Why did Peaches&#39; mom hang on the tree? - Movies &amp; TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...