Asignar matriz 2d de memoria en la función C

¿Cómo asignar memoria dinámica para 2d array en la función? Lo intenté de esta manera:

int main() { int m=4,n=3; int** arr; allocate_mem(&arr,n,m); } void allocate_mem(int*** arr,int n, int m) { *arr=(int**)malloc(n*sizeof(int*)); for(int i=0;i<n;i++) *arr[i]=(int*)malloc(m*sizeof(int)); } 

Pero no funciona.

upd: función corregida (respuesta rápida)

 void allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n*sizeof(int*)); for(int i=0; i<n; i++) (*arr)[i] = (int*)malloc(m*sizeof(int)); } 

Su código es incorrecto en *arr[i]=(int*)malloc(m*sizeof(int)); porque la precedencia del operador [] es más alta que el * operador de deferencia: en la expresión *arr[i] , se evalúa primero arr[i] luego * se aplica. Lo que necesita es lo inverso ( arr referencia de referencia, luego aplique [] ).

Utilice paréntesis como este: (*arr)[i] para anular la precedencia del operador. Ahora, su código debería verse así:

 void allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n*sizeof(int*)); for(int i=0; i 

Para comprender mejor lo que sucede en el código anterior, lea esta respuesta .

Es importante que siempre desasigne explícitamente la memoria asignada dinámicamente una vez que haya terminado de trabajar con ella. Para liberar la memoria asignada por la función anterior, debe hacer esto:

 void deallocate_mem(int*** arr, int n){ for (int i = 0; i < n; i++) free((*arr)[i]); free(*arr); } 

Además, una mejor forma de crear una matriz 2D es asignar memoria contigua con una sola llamada a la función malloc() como se muestra a continuación:

 int* allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n * sizeof(int*)); int *arr_data = malloc( n * m * sizeof(int)); for(int i=0; i 

Para desasignar esta memoria:

 void deallocate_mem(int*** arr, int* arr_data){ free(arr_data); free(*arr); } 

Tenga en cuenta que en la segunda técnica, Malloc se llama solo dos veces, por lo que en el código de desasignación, Free se llama solo dos veces en lugar de llamarlo en bucle. Entonces esta técnica debería ser mejor.

Si no es necesario cambiar el tamaño de su matriz (bueno, puede hacerlo, pero será un poco más complicado), existe una forma más fácil / más eficiente de construir matrices 2D en C.

Eche un vistazo a http://c-faq.com/aryptr/dynmuldimary.html .

El segundo método (para el arreglo llamado array2) es bastante simple, menos doloroso (intente agregar las pruebas para el valor de retorno de Mallocs), y mucho más eficiente.

Acabo de compararlo, para una matriz de 200×100, asignada y desasignada 100000 veces:

  • Método 1: 1.8s
  • Método 2: 47 ms

Y los datos en la matriz serán más contiguos, lo que puede acelerar las cosas (puede obtener algunas técnicas más eficientes para copiar, restablecer … una matriz asignada de esta manera).

Considere esto: solo asignación única

 int** allocate2D(int m, int n) { int **a = (int **)malloc(m * sizeof(int *) + (m * n * sizeof(int))); int *mem = (int *)(a + m); for(int i = 0; i < m; i++) { a[i] = mem + (i * n); } return a; } 

Liberar:

 free(a); 

Al asignar la memoria en muchos bloques diferentes, uno puede asignar esto en un bloque de memoria consecutiva. Haz lo siguiente:

 int** my2DAllocation(int rows,int columns) { int i; int header= rows *sizeof(int *); int data=rows*cols*sizeof(int); int ** rowptr=(int **)malloc(header+data); if(rowptr==NULL) { return NULL: } int * buf=(int*)(rowptr+rows); for(i=0;i 

Esa es una forma innecesariamente complicada de asignar espacio para una matriz. Considera esto:

 int main(void) { size_t m = 4, n = 3; int (*2D_array)[m]; 2D_array = malloc(n * sizeof *2D_array); free(2D_array); return 0; } 

He intentado con el siguiente código para asignar memoria a una matriz bidimensional.

  #include #include void main(void) { int **p;//double pointer holding a 2d array int i,j; for(i=0;i<3;i++) { p=(int**)(malloc(sizeof(int*)));//memory allocation for double pointer for(j=(3*i+1);j<(3*i+4);j++) { *p = (int*)(malloc(sizeof(int)));//memory allocation for pointer holding integer array **p = j; printf(" %d",**p);//print integers in a row printf("\n"); p++; } } } 

La salida del código anterior es:

1 2 3

4 5 6

7 8 9

Para comprender una matriz bidimensional en términos de indicadores, debemos entender cómo se asignará en la memoria, debería ser algo como esto:

  1 2 3 1000 --> 100 104 108 4 5 6 1004 --> 200 204 208 7 8 9 1008 --> 300 304 308 

de lo anterior, entendemos que, cuando asignamos memoria al puntero p, que es un puntero doble, apunta a una matriz de enteros, por lo que en este ejemplo, vemos que el 0x1000 es el puntero p.

Este puntero apunta al puntero entero * p que es una matriz de enteros, cuando la memoria está asignada dentro del ciclo for interno, durante la primera iteración el puntero es 0x100 que apunta al valor entero 1, cuando asignamos ** p = j. De manera similar, apuntará a 2 y 3 en las siguientes iteraciones en el ciclo.

Antes de la próxima iteración del bucle externo, se incrementa el doble puntero, dentro de la siguiente iteración, como se ve en este ejemplo, el puntero ahora está en 0x1004 y apunta al puntero entero, que es una matriz de números enteros 4,5,6 y de manera similar para las siguientes iteraciones en el ciclo.

Array 2D Array dinámicamente usando malloc:

 int row = 4; int column = 4; int val = 2; // memory allocation using malloc int **arrM = (int**)malloc (row*sizeof(int*)); for (int i=0;i
		      	

Pruebe el siguiente código:

  void allocate_mem(int*** arr,int n, int m) { *arr=(int**)malloc(n*sizeof(int*)); for(int i=0;i