Publi

Reservar dinámicamente memoria para un array bidimensional en C

led_array
Uno de los grandes defectos de un array, es que en tiempo de codificación debemos definir el tamaño que tendrá en tiempo de ejecución. A veces, es lo más fácil y está bien, lo utilizamos, puede que malgastemos unos bytes, pero no pasa nada, otras veces es una variable de un tamaño justo y no nos excedemos. Pero muchas veces, el gran problema, es que no tenemos ni idea de cuánto tamaño darle; si le damos poco, porque nos quedamos cortos, si nos pasamos, porque malgastaremos varios Megabytes, y a veces sabemos que incluso aunque algunas veces se desperdicie gran cantidad de memoria habrá casos en los que nos quedamos cortos.

Por eso, entre nuestras herramientas tenemos la reserva dinámica de memoria, creamos un puntero en cualquier momento y podemos reservar la memoria que queramos, tenemos las herramientas malloc y calloc. Aunque como mucho, son capaces de reservar memoria para una estructura similar a un array unidimensional. Se podrá reservar memoria para una variable o una colección de variables.

Si queremos reservar dos o más dimensiones, tendremos que llamar varias veces a las funciones de reserva de memoria, en este caso, yo he utilizado calloc, aunque se podría utilizar malloc perfectamente. Para ello, primero reservamos X punteros a nuestro dato y luego recorremos todos esos punteros y dentro de cada uno de ellos reservamos Y espacios para alojar nuestro dato; por ejemplo , para una matriz entera, primero reservamos filas de punteros y luego por cada fila reservamos columnas de datos.

Lo bueno, es disponer de una función con la que fácilmente se pueda reservar y liberar memoria (la liberación tiene primero que recorrer y liberar cada fila):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdlib.h>
#include <stdio.h>

void** calloc2d (int rows, int cols, int elemSize)
{
  void **variable;
  int i;

  variable=(void**)calloc(rows, sizeof(void*));
 
  for (i=0; i<rows; i++)
    {
      variable[i]=calloc(cols, elemSize);
    }
  return variable;
}

void free2d (void **var, int rows)
{
  int i;
  for (i=0; i<rows; i++)
    free(var[i]);

  free(var);
}

void randomValues(int **v, int rows, int cols)
{
  int i,j;
  for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
      v[i][j]=rand();
}

int main(int argc, char *argv[])
{
  int rows=10000;
  int cols=20000;
  getchar();
  int ** v=(int**)calloc2d(rows, cols, sizeof(int));

  randomValues(v, rows, cols);
  getchar();

  free2d((void**)v, rows);
  getchar();
  return EXIT_SUCCESS;
}

La primera función calloc2d() reservará dinámicamente los arrays bidimensionales indicando filas y columnas), free2d() liberará la memoria especificando sólo las filas. La función randomValues() es un extra que asigna valores aleatorios a los enteros del array, para utilizar la memoria reservada, así utilianzo algún programa que visualice la memoria ocupada por el proceso nos indique cuánto ocupa.

El programa hará tres pausas, una antes de hacer nada (pulsamos intro, para que salgamos del getchar()), otra cuando ha reservado toda la memoria, y otra cuando la haya liberado).

Hay que tener cuidado al ejecutar el programa tal cual si tenemos poca RAM, 10000 (rows) * 20000 (cols) * 4 (sizeof(int)) = 800000000 = 8 * 10^8 unos 800Mb

Foto: cibomahto (Flickr) Creative Commons a día 27/05/2012

También podría interesarte...

There are 2 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Pingback: BlogESfera.com /

Leave a Reply