Вопрос по c, struct, malloc – Что является причиной гибкого члена массива не в конце ошибки структуры?

18

Мне интересно, почему я продолжаю получатьerror: flexible array member not at end of struct ошибка при вызове malloc. У меня есть структура с массивом переменной длины, и я продолжаю получать эту ошибку.

Структура есть,

typedef struct {
  size_t N;
  double data[];
  int label[];
} s_col; 

и вызов Malloc есть,

col = malloc(sizeof(s_col) + lc * (sizeof(double) + sizeof(int)));

Это правильный вызов malloc?

Ваш Ответ

3   ответа
3

необходимо, чтобы компилятор C имел доступ к любому члену структуры без необходимости доступа к чему-либо еще. Поскольку местоположение каждого элемента в структуре определяется количеством и типами элементов, предшествующих ему, для доступа к любому элементу требуется, чтобы число и типы всех предыдущих элементов были известны. В конкретном случае, когда последний элемент является массивом, это не представляет особой трудности, поскольку для доступа к элементу в массиве требуется знание, с чего он начинается (что требует знания числа и типаpreceding элементы, а не количество элементов в самом массиве) и индекс элемента (который компилятор может считать меньшим, чем число элементов, для которых существует пространство, без необходимости что-либо знать о размере массива). Если бы элемент гибкого массива появлялся где-то, кроме конца структуры, местоположение любых элементов, которые следовали за ним, зависело бы от количества элементов в массиве - что-то, что компилятор не собирается знать.

3
typedef struct {
  size_t N;
  double data[];
  int label[];
} s_col; 

double data[]) в середине. Учитывайте размер закодированного массива илиdouble *data

Я не понимаю, меня учили, что "T * var" такой же, как & quot; T var [] & quot;
@ lukasz1985: То, что вы говорите, является верным в контексте аргумента функции, где вы можете указать & quot; аргумент, манипулирующий массивом & quot; который технически реализован с помощью указателя. Обычно (то есть здесь) массив - это массив, а указатель - это указатель.
20

и он всегда должен быть последним членом структуры. Другими словами, в этом случае вы ошиблись, прежде чем позвонитьmallocдо такой степени, что на самом деле нет способа позвонитьmalloc правильно для этой структуры.

Чтобы делать то, что вы, кажется, хотите (массивы того же числаdata а такжеlabel члены), вы могли бы рассмотреть что-то вроде:

struct my_pair { 
    double data;
    int label;
};

typedef struct { 
   size_t N;
   struct my_pair data_label[];
};

Обратите внимание, что это несколько иное: вместо массиваdoubleс последующим массивомints, он дает вам массив из одногоdouble сопровождаемый однимintтогда следующийdouble, следующийint, и так далее. Будет ли это достаточно близко к одному и тому же или нет, будет зависеть от того, как вы используете данные (например, для передачи во внешнюю функцию, которая ожидает непрерывный массив, вам, вероятно, придется делать вещи по-другому).

Похожие вопросы