Выделите память для гибкого массива в структуре

Я пытаюсь выделить память для структуры, используя flexarray. Я получил это таким образом, и я должен реализовать это следующим образом.

Структура выглядит так:

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

У меня есть функция, которая инициирует структуру. Именно там у меня проблема. Я действительно не знаю: мне нужно использовать malloc для выделения памяти для структуры и все, или мне нужно выделять память для *data[] как указатель на массив?

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);
    }

Тогда я должен написать следующий код или нет?

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);
        }
    }

Я надеюсь, что мое объяснение было достаточно ясным. Если нет, я могу попытаться объяснить это снова.

Спасибо!:)

2 ответа

Решение

Как долго ты хочешь imagine->data быть? Кажется, ты хочешь, чтобы это было width элементы длинные, так что сделайте это:

imagine = ( XPM* ) malloc ( sizeof ( XPM ) + sizeof ( unsigned int* ) * width);

Кроме того, актерский состав (XPM*) не нужен в C, но это не строго важно. Это не остановит работу вашего кода.

Это ненужно и неправильно:

imagine -> data = ( unsigned int* ) calloc( width, sizeof( unsigned int ) );
if( !imagine->data ) {
    perror( "Error allocating resources for XPM data width" );
    exit(EXIT_FAILURE);
}

Вы уже выделили память для imagine->data одновременно с imagine сам. Если бы вы объявили unsigned int **data; вместо unsigned int *data[];это было бы правильно. Если бы вы выбрали этот путь, вам нужно было бы выделить только sizeof(XPM) байты для imagine, вместо sizeof(XPM) + sizeof(unsigned int*)*widthпотому что массив imagine->data будет храниться отдельно от структуры imagine,

Остальная часть вашего кода, который выделяет массив для каждой строки пикселей, в порядке.

Вы должны быть в порядке, просто делая что-то вроде:

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;
}

Нет необходимости выполнять ваш второй набор операторов, поскольку выделение для массива данных "unsigned int" уже выделяется в первом наборе.

Другие вопросы по тегам