简体   繁体   中英

Allocate memory for flexible array in structure

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.

You should be ok by simply doing something like:

XPM *initXPM(unsigned int width,
             unsigned int height,
             unsigned char cpp,
             unsigned int ncolors) {

    XPM *imagine = ( XPM* ) malloc ( sizeof ( XPM ) );
    imagine->data = ( unsigned int *) malloc ( sizeof ( unsigned int ) * width * height);

    if(!imagine) {
        perror( "Error allocating resources for XPM structure" );
        exit(EXIT_FAILURE);
    }

    ...

    return imagine;
}

There is no need to execute your second set of statements, as the allocation for the array of 'unsigned int' data is already being allocated in the first set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM