Определение структуры C, содержащее тип двумерного массива

Я хочу включить указатель двумерного массива переменной длины как часть структуры, но компилятор c99 выдает следующую ошибку в строке Array anArray: "член гибкого массива в пустой структуре".

typedef const int Array[][2];

typedef struct {
    Array anArray;
} StructType;

Array myArray = {{1,2},{3,4},{5,6}};

StructType myStruct = { myArray };

Я был бы признателен за любое понимание этой проблемы и решения. Со временем я добавлю другие компоненты в StructType.


person Rick N.    schedule 25.11.2017    source источник
comment
Я не совсем понимаю, что вы хотите сделать.   -  person user2736738    schedule 25.11.2017
comment
Гибкие массивы разрешены только в качестве последнего элемента struct с более чем одним именованным элементом; у вас не может быть struct, единственным элементом которого является гибкий массив. И после исправления этого я не верю, что вам разрешено инициализировать гибкие массивы так, как вы это делаете.   -  person AlexP    schedule 25.11.2017
comment
Это не указатель массива. Это массив. И определение с таким FAM в любом случае будет совершенно бесполезным, потому что присваивание структуры не будет копировать массив, поэтому в любом случае вам придется использовать memcpy. А что говорит о том, сколько элементов в этом массиве?! ничего.   -  person Antti Haapala    schedule 25.11.2017


Ответы (3)


Структура должна знать размер массива, а здесь упускается одно измерение. Если объявление и инициализация были выполнены одновременно, вы могли бы, например,

int Array[][2] = {{1,2},{3,4},{5,6}};

затем компилятор создает пространство для массива и устанавливает значение (в противном случае это должно быть во время выполнения с использованием динамического распределения).

Во-вторых, в C, к сожалению, такой практичный способ инициализации массива невозможен.

 StructType myStruct = { myArray };

Это нужно было бы сделать во время выполнения (и у C были бы некоторые проблемы с выполнением такого рода присваивания, например, в случае динамического распределения, поскольку нет механизма для поддержания размеров объектов в актуальном состоянии).

Однако вы можете установить размер недостающего измерения и скопировать массив благодаря функции памяти memcpy

typedef const int Array[3][2];

typedef struct {
    Array anArray;
} StructType;

int main(int argc, char **argv) {

    Array myArray = {{1,2},{3,4},{5,6}};

    StructType myStruct;
    memcpy(myStruct.anArray,myArray,sizeof(myArray));

Вы также можете сделать объявление структуры и инициализацию таким образом

StructType myStruct = { {{1,2},{3,4},{5,6}} };

а в С99 даже

StructType myStruct = { .anArray = {{1,2},{3,4},{5,6}} };
person Breaking not so bad    schedule 25.11.2017

Спасибо за комментарии. Я изменил код на следующий, и теперь он компилируется.

typedef const int Array[][2];

typedef const struct {
    int something;
    Array *pAnArray;
} StructType;

Array myArray = {{1,2},{3,4},{5,6}};

StructType myStruct = { 0, &myArray };
person Rick N.    schedule 25.11.2017

То, что вы сделали, не зная, — это создание структуры с гибким элементом массива. Обычно в C все члены структур и объединений должны иметь полные типы, т. е. их длина должна быть точно известна во время компиляции. Однако существует исключение для последнего члена, которому это не нужно, но вместо этого он становится "гибким элементом массива" . Проблема в вашем случае в том, что у вас нет других членов в структуре, и это не законно (я не могу придумать убедительного обоснования, почему это atm). Хранение указателя в структуре, конечно, не равно сохранению полного массива, но, вероятно, это больше похоже на то, что вы хотите (по крайней мере, как новичок).

person stefanct    schedule 30.11.2017