Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Metal-byte en 22 Enero 2012, 15:11 pm



Título: Expandir matriz dinámica?
Publicado por: Metal-byte en 22 Enero 2012, 15:11 pm
El asunto es este. Estoy creando una matriz dinámica de 3 de ancho (fijo) por n filas de alto con la función calloc.

Mi consulta es como quitarle o agregarle filas a esa matriz en tiempo de ejecución. Tengo entendido que puedo hacerlo mediante la función realloc, pero no entiendo como funcionaría en este caso (La he probado solo en arrays dinámicos, pero nunca en matrices :/)

Saludos.


Título: Re: Expandir matriz dinámica?
Publicado por: Akai en 22 Enero 2012, 18:29 pm
Imagino que la matriz dinámica la crearás de un modo similar a:

Código
  1. int **matriz
  2.  
  3. matriz=(int **) calloc(num_filas,sizeof(int*));
  4.  
  5. for(i=0;i<num_filas;i++){
  6.    matriz[i]=(int *) calloc(3,sizeof(int));
  7.  
  8.  

Para modificar el numero de filas:

Código
  1.  
  2. matriz= (int **) realloc(matriz,num_fila_nuevo*sizeof(int*));
  3.  
  4. if(num_fila_nuevo> num_fila){ //tendremos que añadir columnas si hemos ampliado el numero de filas
  5.  
  6.    for(i=num_fila;i<num_fila_nuevo;i++){
  7.        matriz[i]=(int *) calloc(3,sizeof(int));
  8.    }
  9.  
  10. }
  11. num_fila=num_fila_nuevo
  12.  



Título: Re: Expandir matriz dinámica?
Publicado por: rir3760 en 22 Enero 2012, 23:06 pm
Mi consulta es como quitarle o agregarle filas a esa matriz en tiempo de ejecución. Tengo entendido que puedo hacerlo mediante la función realloc, pero no entiendo como funcionaría en este caso (La he probado solo en arrays dinámicos, pero nunca en matrices :/)
Si se reserva la memoria en la forma usual solo tienes que seguir la explicación de Akai teniendo cuidado de, si el numero de filas se reduce, primero liberar esas filas.

Si como indicas el numero de columnas por fila es fijo puedes utilizar un puntero a array y reservar todo el bloque mediante malloc/realloc sin tener que preocuparte por reservas individuales.

Un programa de ejemplo en C sobre esto ultimo (sin validación de errores para acortar):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define NUM_FILAS  6
  5. #define NUM_COLS   3
  6.  
  7. int main(void)
  8. {
  9.   int (*p)[NUM_COLS];
  10.   int num_filas = NUM_FILAS;
  11.   int i;
  12.   int j;
  13.  
  14.   /* Reserva y asignacion */
  15.   p = malloc(num_filas * sizeof *p);
  16.   for (i = 0; i < num_filas; i++)
  17.      for (j = 0; j < NUM_COLS; j++)
  18.         p[i][j] = 10 * i + j;
  19.  
  20.   /* Impresion */
  21.   for (i = 0; i < num_filas; i++){
  22.      for (j = 0; j < NUM_COLS; j++)
  23.         printf("%3d", p[i][j]);
  24.  
  25.      putchar('\n');
  26.   }
  27.  
  28.   puts("---------");
  29.  
  30.   /* Reajuste (Capacidad a la mitad) */
  31.   num_filas /= 2;
  32.   p = realloc(p, num_filas * sizeof *p);
  33.  
  34.   /* Impresion */
  35.   for (i = 0; i < num_filas; i++){
  36.      for (j = 0; j < NUM_COLS; j++)
  37.         printf("%3d", p[i][j]);
  38.  
  39.      putchar('\n');
  40.   }
  41.  
  42.   free(p);
  43.  
  44.   return EXIT_SUCCESS;
  45. }

Un detalle: si la función realloc falla esta retorna NULL y el puntero pasado como primer argumento continua siendo valido. Hay que considerar eso cuando se agrega validación de errores.

Un saludo