Page 263

4 Estructuras de datos: memoria din´amica

CC 2003, 2008 Andr´ es Marzal e Isabel Gracia

Redimensionamiento con holgura Estamos utilizando realloc para aumentar de celda en celda la reserva de memoria de los vectores que necesitan crecer. Este tipo de redimensionamientos, tan ajustados a las necesidades exactas de cada momento, nos puede pasar factura: cada operaci´ on realloc es potencialmente lenta, pues ya sabes que puede disparar la copia de un bloque de memoria a otro. Una t´ecnica para paliar este problema consiste en crecer varias celdas cada vez que nos quedamos cortos de memoria en un vector. Un campo adicional en el registro, llam´emosle capacidad , se usa para indicar cu´ antas celdas tiene reservadas un vector y otro campo, digamos, talla, indica cu´ antas de dichas celdas est´ an realmente ocupadas. Por ejemplo, este vector, en el que s´ olo estamos ocupando de momento tres celdas (las marcadas en negro), tendr´ıa talla igual a 3 y capacidad igual a 5: 0

1

2

3

4

a Cada vez que necesitamos escribir un nuevo dato en una celda adicional, comprobamos si talla es menor o igual que capacidad . En tal caso, no hace falta redimensionar el vector, basta con incrementar el valor de talla. Pero en caso contrario, nos curamos en salud y redimensionamos pidiendo memoria para, pongamos, 10 celdas m´ as (y, consecuentemente, incrementamos el valor de capacidad en 10 unidades). De este modo reducimos el n´ umero de llamadas a realloc a una d´ecima parte. Incrementar un n´ umero fijo de celdas no es la u ´nica estrategia posible. Otra aproximaci´ on consiste en duplicar la capacidad cada vez que se precisa agrandar el vector. De este modo, el n´ umero de llamadas a realloc es proporcional al logaritmo en base 2 del n´ umero de celdas del vector. 1 2 3 4

struct VDH { // vector Din´ amico con Holgura (VDH) int * dato; int talla, capacidad ; };

5 6 7

struct VDH crea_VDH (void) { struct VDH vdh;

8

vdh.dato = malloc(1*sizeof (int)); vdh.talla = 0; vdh.capacidad = 1; return vdh;

9 10 11

}

12 13 14 15 16 17 18 19 20

void anyade_dato(struct VDH * vdh, int undato) { if (vdh->talla == vdh->capacidad ) { vdh->capacidad *= 2; vdh->dato = realloc(vdh->dato, vdh->capacidad * sizeof (int)); } vdh->dato[vdh->talla++] = undato; }

21 22 23 24 25 26 27 28 29

void elimina_ultimo(struct VDH * vdh) { if (vdh->talla < vdh->capacidad /2 && vdh->capacidad > 0) { vdh->capacidad /= 2; vdh->dato = realloc(vdh->dato, vdh->capacidad * sizeof (int)); } vdh->talla--; }

Ciertamente, esta aproximaci´ on ((desperdicia)) memoria, pero la cantidad de memoria desperdiciada puede resultar tolerable para nuestra aplicaci´ on. Python usa internamente una variante de esta t´ecnica cuando modificamos la talla de una lista con, por ejemplo, el m´etodo append (no duplica la memoria reservada, sino que la aumenta en cierta cantidad constante).

Introducci´ on a la Programaci´ on con C

257

Profile for esLibre.com

Introducción a la programación con c  

Introducción a la programación con c  

Advertisement