7

Tengo un problema con un proyecto. Tengo que hacer una matriz 2D de tamaño variable para almacenar algún error de predicción ... así que esto es sobre imágenes. El problema es que tengo que cargar imágenes de diferentes tamaños, así que para cada imagen tendré que ingresar a un archivo la matriz 2D con el número correspondiente de píxeles. He buscado entre sus preguntas, pero no es lo que estoy buscando. por. ¿Puede alguien ayudarme?¿Cómo declarar una matriz 2D de tamaño variable en C?

Gracias

Respuesta

0

Es necesario asignar memoria dinámicamente. Use la lógica de doble puntero.

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

Ningún puntero doble no es una matriz multidimensional. –

+0

Ciertamente no, pero puede hacerlo funcionar como una matriz – Akshay

+0

¿Por qué usar una emulación de una matriz 2D cuando simplemente puede usar una? –

6

Si usted tiene un compilador de C moderna (al menos C99) en el ámbito de la función es tan simple como:

unsigned arr[n][m]; 

esto se llama una matriz de longitud variable (VLA) Puede tener problemas si la matriz es demasiado grande. Así que si usted tiene grandes imágenes que podría hacer:

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

y más tarde

free(arr); 
+0

Recuerde que la matriz de longitud variable mencionada anteriormente se asignará en la pila. Lo segundo que no es muy relevante para la pregunta es que C++ 0X no es compatible con esta característica (sin embargo, dado que esta es una pregunta C, funciona bien) – Yavar

+0

@Yavar, así que también mencioné la versión asignada con 'malloc' . E incluso entonces es un "tipo modificado variablemente". Y C++ claramente tiene otras formas de hacer arreglos multidimensionales, así que sí, esto no es relevante en absoluto. –

0

Por ejemplo, si se tiene en cuenta la asignación de un int matriz 2D:

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

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

donde nfilas -> sin de filas ncols -> ninguna de las columnas son const o # define's

2

Si necesita que la memoria sea contigua, tiene un par de elecciones.

Se podría asignar dinámicamente un solo bloque de memoria, y luego calcular sus desplazamientos de forma manual, así:

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

podría configurar una segunda matriz de punteros en la matriz principal:

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

recordando que tendrías que liberar arr y arrp.

Si usted tiene una aplicación C99, sólo puede configurar un puntero a un VLA, así:

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

Tenga en cuenta que en este caso, usted no está cualquier reserva de memoria para una matriz secundaria, tampoco es necesario calcular manualmente los punteros en la matriz principal; todo lo que tiene que hacer es establecer arrp en la misma ubicación que arr y dejar que las reglas de la aritmética del puntero hagan todo el trabajo.

Si las imágenes no son tan grandes, que sólo podría configurar una VLA (de nuevo, C99 o posterior):

int arr[rows][cols]; 

pero en la práctica esto no es una buena idea; los marcos de pila generalmente son bastante limitados en tamaño.

+0

En su tercer caso, creo que la asignación está mejor hecha ya que la di en mi respuesta. Simplemente 'malloc' directamente, no hay necesidad de lanzar, esto solo se ofusca. –

Cuestiones relacionadas