Arrays bidimensionales dinámicos en C

Por Jose | 4 de Enero de 2010 a las 18:25 |

A veces nos encontramos resolviendo un problema en C, Pascal u otro lenguaje y necesitamos almacenar datos que cambian dinámicamente en cada ejecución, como un programa que se encargue de realizar operaciones con matrices, o cargar una foto en memoria para rotarla.
Si no queremos “perder” nuestro tiempo más de uno lo que hace es declarar un array bidimensional estático lo suficientemente grande para que “funcione”, pero no es la solución. Lo adecuado es declarar un array dinámico en tiempo de ejecución, veámoslos.

Los arrays dinámicos en C son un poco más laboriosos de entender y crear que en otros lenguajes, pero vamos a perderle el miedo a estes tipos de datos tan usados.

En C un array bidimensional es un array de punteros a punteros, dónde en primer lugar tenemos que saber cuántos elementos vamos a almacenar en el array. Vamos a suponer que queremos almacenar 3 elementos al que llamaremos filas:

int filas = 3;
int **array = (int **) malloc(filas * sizeof(int *));

En el código anterior se ha declarado memoria para tres filas de números enteros, quedando así:
[0] -> “columna sin declarar”
[1] -> “columna sin declarar”
[2] -> “columna sin declarar”

Tenemos tres punteros a enteros (filas) que apuntan a “columna sin declarar”. Por lo tanto, a continuación, reservamos memoria para cada “columna sin declarar”, teniendo en cuenta que queremos que en cada fila se almacenen dos columnas de números enteros.

int columnas = 2;
int i = 0;
for(i=0; i<filas; i++) {
    array[i] = (int *) malloc(columnas * sizeof(int));
}

Ahora ya tendríamos el siguiente array:
[0] -> [0] [1]
[1] -> [0] [1]
[2] -> [0] [1]

En este momento ya podemos manejar el array dinámico como si fuese uno estático, por ejemplo:

/* inicializamos el array */
array[0][0] = 105;

/* inicializamos y visualizamos el array con un bucle for */
for(i=0; i<filas; i++) {
    for(j=0; j<columnas; j++) {
        array[i][j] = rand() % 150;
        printf("array[%d][%d] = %d  ", i, j, array[i][j]);
    }
    printf("\n");
}

Al final del programa ES ACONSEJABLE liberar la memoria del array dinámico. Esto se hace al revés de la creación del array, primero se eliman las columnas y, una vez que ya no haya columnas, se eliminan la filas, así:

/* liberamos la memoria de las columnas */
for(i=0; i&lt;filas; i++) {
    free(array[i]);
}

/* liberamos la memoria de las filas  */
free(array);
array = NULL;

Para terminar vamos a ver el último ejemplo, este es parecido al anterior, pero en vez de trabajar con números enteros vamos a trabajar con arrays de caracteres.
El siguiente programa lo que hace es una copia de los argumentos que le pasamos al programa, visualizándolos por
pantalla y eliminado la memoria previamente reservada.

/**
*  Programa:
*      Arrays dinamicos bidimensionales
*  Descripcion:
*      Programa que hace una copia de argv para mostrar el uso de la
*      reserva dinamica de memoria en arrays bidimensionales
*  Archivo: cargv.c
*  Ejecucion: ./cargv "argumento1" "argumento 2" "argumento n"
*  Compilar: gcc -o cargv cargv.c
*  Autor:
*      Jose Mato
* **/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    int i = 0;
    int filas = 0;
    char **array = NULL;

    /* reservamos memoria para el numero de filas*/
    filas = argc;
    array = (char **) malloc(filas * sizeof(char *));

    /*  vamos recorriendo fila a fila, y para cada una reservamos
         el numero de columnas dinamicamente.
         Almacenamos el valor del argumento
    */
    for(i=0; i<filas; i++) {
        array[i] = (char *) malloc((strlen(argv[i]) + 1) * sizeof(char));
        strcpy(array[i], argv[i]);
    }

    /* mostramos los argumentos del array */
    for(i=0; i<filas; i++) {
        puts(array[i]);
    }

    /* liberamos la memoria del array en orden inverso al de creacion:
        primero las columnas y despues las filas */
    for(i=0; i<filas; i++) {
        free(array[i]);
        array[i] = NULL;
    }

    /* liberamos los punteros de las filas */
    free(array);
    array = NULL;

    return EXIT_SUCCESS;
}

Espero que os haya servido de ayuda y resolviese vuestras dudas. Y tú, ¿para qué los usaste?

Descargar: programa cargv.c

Posts Relacionados

No hay posts relacionados... premio de consolación: .

Dejar un comentario




XHTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>