I am trying to allocate memory for a structure using a flexarray. I received it this way and I have to implement it like this.
The structure looks like:
struct _XPM {
unsigned int width;
unsigned int height;
unsigned char cpp;
unsigned int ncolors;
Color *colta;
unsigned int *data[];
}; //it's a typedef to XPM in the headder file
I have a function that initiates the structure. It is there where I have the problem. I really don't know: do I have to use malloc to allocate memory for the structure and that's it, or do I need to allocate memory to *data[]
like a pointer to an array?
void initXPM(XPM *imagine,
unsigned int width,
unsigned int height,
unsigned char cpp,
unsigned int ncolors) {
imagine = ( XPM* ) malloc ( sizeof ( XPM ) + sizeof ( unsigned int* ) * width * height );
/* I think I need to allocate sizeof(unsigned int) *width * height because
I have to work with an array of pixels */
if(!imagine) {
perror( "Error allocating resources for XPM structure" );
exit(EXIT_FAILURE);
}
Then do I have to write the following code or not?
imagine -> data = ( unsigned int* ) calloc( width, sizeof( unsigned int ) );
if( !imagine->data ) {
perror( "Error allocating resources for XPM data width" );
exit(EXIT_FAILURE);
}
for( i = 0; i < width; i++ ) {
imagine -> data[i] = (unsigned int*) calloc ( height, sizeof(unsigned int) );
if( !imagine -> data[i] ) {
perror( "Error allocating resources for XPM data height" );
exit(EXIT_FAILURE);
}
}
I hope my explanation was clear enough. If not, I can try to explain it again.
Thank you! :)
How long do you want imagine->data
to be? It seems that you want it to be width
elements long, so do this:
imagine = ( XPM* ) malloc ( sizeof ( XPM ) + sizeof ( unsigned int* ) * width);
Also, the cast (XPM*)
is unnecessary in C, but that's not strictly important. It won't stop your code working.
This is unnecessary and wrong:
imagine -> data = ( unsigned int* ) calloc( width, sizeof( unsigned int ) );
if( !imagine->data ) {
perror( "Error allocating resources for XPM data width" );
exit(EXIT_FAILURE);
}
You already allocated the memory for imagine->data
at the same time as imagine
itself. If you had declared unsigned int **data;
instead of unsigned int *data[];
, this would be correct. If you had chosen that way, you would need to allocate only sizeof(XPM)
bytes for imagine
, instead of sizeof(XPM) + sizeof(unsigned int*)*width
, because the array imagine->data
would be stored separately from the structure imagine
.
The rest of your code, which allocates an array for each row of pixels, is fine.