7

У меня проблема с проектом. Я должен сделать 2D-массив с переменным размером для хранения некоторой ошибки предсказания. Это касается изображений. Проблема в том, что мне приходится загружать изображения разных размеров, поэтому для каждого изображения я должен был бы получить в файл 2D-массив с соответствующим количеством пикселей. Я искал среди ваших вопросов, но это не то, что я ищу за. Кто-нибудь может мне помочь?Как объявить переменный размер 2D-массива в C?

Спасибо

ответ

0

Вам нужно выделить память динамически. Используйте логику с двойным указателем.

Ex:

int n=10; <<-u can change this. 
int **a; 
a=(int **)malloc(sizeof(*int)*n); 
for (int i=0;i<n;i++){ 
a[i]=(int *)malloc(sizeof(int)*n);// or *(a+i) 
} 
+1

Нет двойной указатель не многомерный массив. –

+0

Конечно нет, но вы можете заставить его вести себя как массив – Akshay

+0

Зачем использовать эмуляцию двумерного массива, когда вы просто можете его использовать? –

6

Если у вас есть современный C компилятор (по крайней мере C99) в области видимости функции это просто:

unsigned arr[n][m]; 

это называется массив переменной длины (VLA). У него могут быть проблемы, если массив слишком велик. Так что если у вас есть большие изображения, которые вы можете сделать:

unsigned (*arr)[m] = malloc(sizeof(unsigned[n][m])); 

и позже

free(arr); 
+0

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

+0

@Yavar, вот почему я также упомянул версию, выделенную 'malloc' , И даже тогда это «измененный тип». И C++ явно имеет другие способы делать многомерные массивы, так что да, это совсем не актуально. –

0

Для примера, если вы рассмотреть вопрос о выделении 2D Int массив:

int **array1 = (int**) malloc (nrows *sizeof(int*)); 

for (int i=0; i<nrows;i++) 
    array1[i]=(int*) malloc (ncols *sizeof(int)); 

где Nrows -> нет строк ncols -> no столбцов являются константами или # define

2

Если вам нужна память, чтобы быть смежной, у вас есть пара выбор.

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

size_t rows, cols; 
... 
int *arr = malloc(sizeof *arr * rows * cols); 
... 
arr[i * rows + j] = ...; // logically equivalent to arr[i][j] 

Вы можете создать второй массив указателей на основной массив:

int **arrp = malloc(sizeof *arrp * rows); 
... 
for (i = 0; i < rows; i++) 
    arrp[i] = &arr[i * rows]; 
... 
arrp[i][j] = ...; 

Помня, что вам нужно было бы освободить иarr и arrp.

Если у вас есть реализация C99, вы можете просто установить указатель на VLA, например, так:

int (*arrp)[cols] = (int (*)[cols]) arr; 
... 
arrp[i][j] = ...; 

Обратите внимание, что в этом случае, вы не выделять какой-либо памяти для вторичного массива, и вам не нужно вручную вычислять указатели в основной массив; все, что вам нужно сделать, это установить arrp в том же месте, что и arr, и пусть правила арифметики указателя выполняют всю работу.

Если изображения не настолько большой, вы можете просто настроить VLA (опять же, C99 или более поздней версии):

int arr[rows][cols]; 

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

+0

В вашем третьем случае я думаю, что распределение лучше сделано, как я дал его в своем ответе. Просто 'malloc' напрямую, нет необходимости бросать, это только запутывает. –

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