7

Ho un problema con un progetto. Devo creare un array 2D di dimensioni variabili per archiviare qualche errore di predizione ... quindi si tratta di immagini. Il problema è che devo caricare immagini di dimensioni diverse, quindi per ogni immagine dovrei inserire in un file l'array 2D con il numero corrispondente di pixel ... ho cercato tra le tue domande ma non è quello che sto cercando for.Can qualcuno mi aiuti?Come dichiarare una matrice 2D di dimensioni variabili in C?

Grazie

risposta

0

È necessario allocare la memoria in modo dinamico. Usa la logica del doppio puntatore.

Es:

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

Nessun puntatore doppio non è un array multidimensionale. –

+0

Certo che no, ma puoi farlo funzionare come un array – Akshay

+0

Perché utilizzare un'emulazione di un array 2D quando puoi semplicemente usarne uno? –

6

Se ha un moderno compilatore C (almeno C99) portata funzione è semplice come:

unsigned arr[n][m]; 

questo è chiamato una matrice di lunghezza variabile (VLA). Potrebbe avere problemi se l'array è troppo grande. Quindi, se avete immagini di grandi dimensioni che si possa fare:

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

e successivamente

free(arr); 
+0

Ricordare che la matrice di lunghezza variabile sopra menzionata sarà allocata sullo stack. La seconda cosa che non è molto pertinente alla domanda è che C++ 0X non supporta questa funzione (tuttavia poiché questa è una domanda C quindi funziona bene) – Yavar

+0

@Yavar, beh, ecco perché ho menzionato anche la versione assegnata con 'malloc' . E anche allora è un "tipo variabilmente modificato". E C++ ha chiaramente altri modi per fare array multidimensionali, quindi sì, questo non è affatto rilevante. –

0

Per un esempio, se si considera l'allocazione di un array di int 2D:

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

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

dove nrows -> no di righe ncols -> no di colonne sono const o # define

2

Se hai bisogno di memoria contigua, hai un paio di scelte.

Si potrebbe allocare dinamicamente un unico blocco di memoria, e quindi calcolare le vostre offset manualmente, in questo modo:

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

è possibile impostare un secondo array di puntatori nella matrice principale:

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

ricordando che è necessario liberare siaarr e arrp.

Se si dispone di un'implementazione C99, si può semplicemente impostare un puntatore ad un VLA, in questo modo:

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

nota che in questo caso, non si è allocare la memoria per un array secondario, né è necessario calcolare manualmente i puntatori nell'array principale; tutto quello che devi fare è impostare arrp nella stessa posizione di arr e lasciare che le regole dell'aritmetica dei puntatori facciano tutto il lavoro.

Se le immagini non sono così grandi, si può solo impostare un VLA (di nuovo, C99 o successiva):

int arr[rows][cols]; 

ma in pratica questo non è una buona idea; i telai dello stack sono generalmente di dimensioni piuttosto limitate.

+0

Nel tuo terzo caso, penso che l'allocazione sia meglio fatta come ho dato nella mia risposta. Proprio 'malloc' direttamente, non c'è bisogno di lanciare, questo solo offusca. –