2015-11-30 2 views
0

Я хочу использовать двумерную матрицу внутри некоторой структуры:Ошибка при использовании многомерного массива из 0 длиной

typedef struct{ 
    int rows; 
    int cols; 
    another_struct *array[][]; 
}some_struct; 

Но, кажется, я не могу сделать многомерный массив неполного типа, поэтому я выбираю идти с another_struct *array[0][0];

И выделить это так:

some_struct *allocate_some_struct(int rows, int cols){ 
    some_struct *p; 
    uint32_t length; 

    length = sizeof(some_struct) + rows * sizeof(another_struct *[cols]); 
    p = malloc(length); 
    p->rows = rows; 
    p->cols = cols; 
    return (p); 
} 

Но всякий раз, когда я пытаюсь открыть его таким образом: ((another_struct *[p->rows][p->cols])p->array)[i], я получаю эту error: used type 'another_struct *[p->rows][p->cols]' where arithmetic or pointer type is required.

(*((another_struct *(*)[p->rows][p-cols])&(p->array)))[i], работа совершенно хорошо. Итак, мои вопросы почему я не могу использовать первый синтаксис? Есть ли принципиальная разница со второй?

+0

Как компилятор знает расположение элементов вашего массива, поскольку он не имеет понятия о количестве строк или столбцов в коде, который не работает, или код, который «отлично работает»? –

+1

Ну, может быть, я должен добавить, чем 'p-> rows = rows;' и 'p-> cols = cols;', что, похоже, позволяет компилятору узнать количество строк и столбцов при кастинге. edit done – Astt

+0

Возможно, вам не нужно явно указывать двумерный массив в структуре 'another_struct * array [] []'. Вы можете просто объявить указатель и хранить данные в свободном хранилище, если не возражаете; указатель указывает на память, в которой хранятся нужные вам данные в необходимой форме (2-мерный массив можно рассматривать как массив массива). – Elyasin

ответ

0

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

Но есть временное решение, позволяющее использовать индексирование с помощью скобок [] и не нужно знать какой-либо размер, кроме размера отдельной ячейки. Вы должны использовать указатели, как в этом примере:

double **new_matrix(int rows, int cols) 
{ 
    double **res = malloc(rows * sizeof(double *)); 
    int i; 
    for (i = 0; i < rows; i++) 
     res[i] = malloc(cols * sizeof(double)); 
    return res; 
} 
void free_matrix(double **matrix, int rows) 
{ 
    int i; 
    for (i = 0; i < rows; i++) free(matrix[i]); 
    free(matrix); 
} 
... 
double **matrix = new_matrix(24, 3); 
matrix[12][1] /* will access correctly row 13 and column 2 element */ 
... 
free(matrix, 24); /* will free all allocated memory */ 

Есть решения, которые позволяют выделить всю матрицу (и указатели в одну кучу (и позволяют использовать free(3) непосредственно на матрицу вещи), но я оставьте это как упражнение для читателя :)

Смежные вопросы