Sei sulla pagina 1di 15

Memoria dinmica

Hasta ahora, hemos realizado una administracin de memoria de tipo esttico. Esto
significa que los vectores y matrices creados tienen un tamao fijo que el compilador
conoce en tiempo de compilacin. Sin emargo, es posile que el tamao de dichos
vectores no se conozca a!priori y por lo tanto necesitemos solicitar memoria al sistema
en tiempo de ejecucin. "a administracin de memoria desde este punto de vista recie
el nomre de memoria dinmica.
El tratamiento de memoria dinmica sigue tres pasos fundamentales#
$% &eticin de memoria 'funcin malloc%
(% )tilizacin de dicha memoria para nuestro propsito
*% "ieracin de memoria 'funcin free%
"a funcin malloc posee la siguiente sinta+is#
[
&ara especificar la cantidad de memoria que necesitamos se suele utilizar la funcin
sizeof.
,ominando estas funciones podremos reservar memoria para vectores, matrices, etc-
&ara lierar memoria asignada utilizaremos la funcin free, especificando la direccin
de inicio de la misma. Su sinta+is es la siguiente#
. partir de esta instruccin, la memoria que ha/amos reservado podr ser utilizada por
otros procesos del sistema.
[direcc_inicio] malloc([tamao en bytes]);
[tamao en bytes] sizeof( [tipo definido] );
free( [direcc_inicio] );
a) Vectores dinmicos
012eamos un ejemplo en el que solicitamos al usuario una cierta cantidad de n3meros
para despu4s mostrarlos por pantalla en el mismo orden en el que se introdujeron. .l
principio del programa solicitaremos al usuario cuntos n3meros desea introducir#10
include !stdio"#$
%oid main(%oid)&
int '%ector; 01creo el vector a entero10
int n( i;
printf ()*lementos a introducir+));
scanf (),d)(-n);
%ector . malloc( sizeof(int)'n); 01 peticion de memoria10

for ( i. /; i ! n ; i00)&
printf ()*lemento ,d+)( i);
scanf ( ),d)( -(%ector[i]) );
1
for ( i./; i ! n; i00)&
printf()*lemento ,d . ,d2n)(i(%ector[i]);
1
free(%ector); 01lieracin10
return;
1
vector
b) Matrices dinmicas
El prolema del tratamiento de matrices dinmicas es similar al del tratamiento de
vectores, teniendo en cuenta que una matriz es un %ector de %ectores.
int Matriz[3][4];
include !stdio"#$
%oid main(%oid)&
int ''Matriz; 5'6untero de puntero'5
int nfil( ncol( i( j;
printf ()7ilas+));
scanf ( ),d)( -nfil);
printf ()8olumnas+));
scanf(),d)(-ncol);
matriz . malloc (sizeof (int')'nfil); 5'reser%a de memoria punteros'5
for( i. /; i ! nfil; i00)&
matriz[i] . malloc ( sizeof (int) 'ncol); 5'reser%a de memoria matriz'5
1
for ( i./; i ! nfil; i00)& 5'6re9untamos los %alores'5
for( j . /; j ! ncol; j00)&
printf ()*lemento (,d(,d)+)( i( j);
scanf (),d)( -(Matriz[i][j]));
1
1
for ( i./; i! nfil; i00)& 5':mprimimos los %alores '5
for( j . /; j ! ncol; j00)&
printf ()*lemento (,d(,d) . ,d2n)( i( j( Matriz[i][j]);
1
1
for ( i./; i! nfil; i00)& 5'liberamos la memoria'5
free(Matriz[i]);
1
free(Matriz);
return; 1
5atriz678
5atriz6$8
5atriz6(8
5atriz
c" *structuras dinmicas de datos
En funcin de la forma en que se relacionan e+isten varios tipos de estructuras de datos.
Este tipo de estructuras son autorreferenciadas, es decir, contienen entre sus campos un
puntero de su mismo tipo. "as ms utilizadas son#
pilas
colas
listas
;as pilas
Este tipo de estructuras se caracteriza porque todas las operaciones se realizan en el
mismo lado. Es de tipo ;:7< ' ;ast :n 7irst <ut %, el 3ltimo elemento en entrar es el
primero en salir.
5' *jemplo de una pila" '5
include !stdio"#$
include !conio"#$
include !stdlib"#$
include !alloc"#$
%oid insertar(%oid);
%oid e=traer(%oid);
%oid %isualizar(%oid);
struct pila
&
c#ar nombre[>/];
struct pila 'ant;
1'8?@.AB;;('?BC.AB;;;
main() 5' Dellenar( e=traer y %isualizar '5
&
c#ar opc;
do
&
clrscr(); 5' borramos la pantalla '5
9oto=y(3/(E); 5' columna 3/( fila E '5
printf()F"G :nsertar));
9oto=y(3/(F/);
printf()>"G *=traer));
9oto=y(3/(F>);
printf()3"G Visualizar la pila));
9oto=y(3/(FH);
printf()H"G Ialir));
opc.9etc#( );
sJitc#(opc)
&
case KFK+
insertar( );
breaL;
case K>K+
e=traer( );
breaL;
case K3K+
%isualizar( );
1
1J#ile (opcM.KHK);
1
%oid insertar(%oid)
&
?BC.(struct pila ')malloc(sizeof(struct pila));
clrscr();
printf()Aombre+ ));
9ets(?BCG$nombre);
if (8?@..AB;;)
&
8?@.?BC;
?BCG$ant.AB;;;
1
else
&
?BCG$ant.8?@;
8?@.?BC;
1
1
%oid e=traer(%oid)
&
if (8?@..AB;;) return;
?BC.8?@;
8?@.8?@G$ant;
free(?BC);
1
%oid %isualizar(%oid)
&
if (8?@..AB;;) return;
clrscr();
?BC.8?@;
J#ile (?BCM.AB;;)
&
printf()Aombre+ ,s2n)(?BCG$nombre);
?BC.?BCG$ant;
1
9etc#( );
1
"a estructura tipo que utilizaremos ser 4sta#
struct pila
&
tipo %ariables;
struct pila 'ant;
1'8?@.AB;;('?BC.AB;;;
donde tipo %ariables sern las diferentes variales que guardaremos en la estructura,
struct pila 'ant es un puntero que apunta al elemento de tipo pila introducido
anteriormente, '8?@ ser donde guardaremos el 3ltimo elemento insertado en la pila y
'?BC nos servir para guardar elementos temporalmente y para recorrer la pila al
visualizarla.
.ntes de insertar un elemento, deeremos comproar si la pila est vac/a o no. Si lo
estuviera deeremos insertar el primer elemento#
8?@.?BC;
8?@G$ant.AB;;;
Si ya huiera alg3n elemento crearemos uno nuevo apuntado por ?BC y haremos
que ?BCG$ant apunte a 8?@, que en este momento contiene la direccin del elemento
insertado anteriormente. 9ras esto haremos que 8?@ apunte al 3ltimo elemento
insertado, que ser la nueva caeza de la pila#
?BCG$ant.8?@;
8?@.?BC;
&ara e+traer un elemento de la pila deeremos hacer que ?BC apunte a la misma
direccin que 8?@, despu4s haremos que 8?@ apunte a 8?@G$ant, con lo que el
elemento anterior pasar a ser la caeza de la pila. 9ras esto, solo queda lierar la
memoria de la zona apuntada por ?BC. :o olvides controlar si e+iste alg3n elemento
' si 8?@ es igual a AB;; la pila est vac/a %#
if (8?@..AB;;) return;
?BC.8?@;
8?@.8?@G$ant;
free(?BC);
&or 3ltimo, para visualizar los elementos de la pila, haremos que el puntero au+iliar
?BC apunte a la caeza de la pila, o sea, a 8?@. 9ras esto iremos visualizando el
contenido de la pila, haciendo que ?BC tome la direccin de ?BCG$ant, mientras
?BC sea distinto de AB;;. 9ami4n es importante controlar que la pila no est4 vac/a.
if (8?@..AB;;) return;
?BC.8?@;
J#ile (?BCM.AB;;)
&
printf(),s)(?BCG$nombre);
?BC.?BCG$ant;
1;
Estructura grfica de una pila#
;as colas
Este tipo de estructuras se caracteriza porque insertamos los elementos por un lado y
los e+traemos por el otro lado. Es de tipo 7:7< ' 7irst :n 7irst <ut %, el primer
elemento en entrar es el primero en salir. &ara gestionar la cola utilizaremos 3 punteros '
para la pila solo eran necesarios > %.
5' *jemplo de una cola" '5
include !stdio"#$
include !conio"#$
include !stdlib"#$
include !alloc"#$
%oid insertar(%oid);
%oid e=traer(%oid);
%oid %isualizar(%oid);
struct cola
&
c#ar nombre[>/];
struct cola 'si9;
1'8?@.AB;;('?BC.AB;;('7:A.AB;;;
main() 5' Dellenar( e=traer y %isualizar '5
&
c#ar opc;
do
&
clrscr();
9oto=y(3/(E);
printf()F"G :nsertar));
9oto=y(3/(F/);
printf()>"G *=traer));
9oto=y(3/(F>);
printf()3"G Visualizar la cola));
9oto=y(3/(FH);
printf()H"G Ialir));
opc.9etc#( );
sJitc#(opc)
&
case KFK+
insertar( );
breaL;
case K>K+
e=traer( );
breaL;
case K3K+
%isualizar( );
1
1J#ile (opcM.KHK);
1
%oid insertar(%oid)
&
?BC.(struct cola ')malloc(sizeof(struct cola));
clrscr();
printf()Aombre+ ));
9ets(?BCG$nombre);
?BCG$si9.AB;;;
if (7:A..AB;;)
7:A.8?@.?BC;
else
&
7:AG$si9.?BC;
7:A.?BC;
1
1
%oid e=traer(%oid)
&
if (8?@..AB;;) return;
?BC.8?@;
8?@.8?@G$si9;
free(?BC);
1
%oid %isualizar(%oid)
&
if (8?@..AB;;) return;
clrscr();
?BC.8?@;
J#ile (?BCM.AB;;)
&
printf()Aombre+ ,s2n)(?BCG$nombre);
?BC.?BCG$si9;
1
9etc#();
1
"a estructura que utilizaremos ser#
struct cola
&
tipo %ariables;
struct cola 'si9;
1'8?@.AB;;('?BC.AB;;('7:A.AB;;;
donde tipo %ariables sern las diferentes variales que guardaremos en la estructura,
struct cola 'si9 es un puntero que apunta al elemento de tipo cola introducido a
continuacin, '8?@ ser donde guardaremos el primer elemento insertado en la cola,
'?BC nos servir para guardar elementos temporalmente y para recorrer la cola al
visualizarla y '7:A tomar la direccin del 3ltimo elemento insertado.
.ntes de insertar un elemento, deeremos comproar si la cola est vac/a o no. Si lo
est deeremos insertar el primer elemento#
if (7:A..AB;;)
8?@.7:A.?BC;
Si ya e+istiera alg3n elemento haremos que 7:AG$si9 apunte al elemento de ?BC y
a continuacin haremos que 7:A tome la direccin de ?BC, con lo que 7:A apuntar al
3ltimo elemento insertado.
7:AG$si9.?BC;
7:A.?BC;
&ara e+traer un elemento de la cola haremos que el puntero au+iliar ?BC tome la
direccin del primer elemento insertado, que hemos guardado en 8?@. 9ras esto
haremos que 8?@ apunte a 8?@G$si9, es decir, que tome la direccin del segundo
elemento insertado, que ahora pasar a ser el primero. "uego lieraremos la zona de
memoria apuntada por ?BC#
?BC.8?@; 5' Neberemos controlar Oue no estP %acQa+ if (8?@..AB;;)
return; '5
8?@.8?@G$si9;
free(?BC);
&ara visualizar la cola comproaremos que e+istan elementos, esto es, que 7:A sea
distinto de AB;;. Hecho esto asignaremos a ?BC la direccin de 8?@ e iremos
recorriendo la cola hasta que ?BC sea igual a AB;;.
?BC.8?@; 5' Neberemos controlar Oue no estP %acQa+ if (8?@..AB;;)
return; '5
J#ile(?BCM.AB;;)
&
printf(),s)(?BCG$nombre);
?BC.?BCG$si9;
1
Estructura grfica de una cola#
;as listas
Este tipo de estructuras se caracteriza porque los elementos estn enlazados entre s/,
de manera que adems de las acciones haituales de insertar, e+traer y visualizar
tami4n podremos uscar un elemento. &ara gestionar la lista utilizaremos H punteros.
5' *jemplo de una lista" '5
include !stdio"#$
include !conio"#$
include !stdlib"#$
include !alloc"#$
%oid insertar(%oid);
%oid e=traer(%oid);
%oid %isualizar(%oid);
struct lista
&
int num;
struct lista 'si9;
1'8?@.AB;;('?BC.AB;;('7.AB;;('6.AB;;;
main() 5' Dellenar( e=traer y %isualizar '5
&
c#ar opc;
do
&
clrscr( );
9oto=y(3/(E);
printf()F"G :nsertar));
9oto=y(3/(F/);
printf()>"G *=traer));
9oto=y(3/(F>);
printf()3"G Visualizar la lista));
9oto=y(3/(FH);
printf()H"G Ialir));
opc.9etc#( );
sJitc#(opc)
&
case KFK+
insertar( );
breaL;
case K>K+
e=traer( );
breaL;
case K3K+
%isualizar( );
1
1J#ile (opcM.KHK);
1
5' ? continuacin insertaremos el elemento Oue
%amos a crear en la posicin Oue le corresponda(
teniendo en cuenta Oue la lista deber Ouedar
ordenada de menor a mayor" *l puntero 6 comprueba
si el campo num de un elemento es menor Oue el
campo num del elemento introducido" *l puntero
7 se Ouedar apuntando al elemento de la posicin
anterior al elemento Oue #emos insertado '5
%oid insertar(%oid)
&
?BC.(struct lista ')malloc(sizeof(struct lista));
clrscr( );
printf():ntroduce un nRmero+ ));
scanf(),d)(-?BCG$num);
?BCG$si9.AB;;;
if (8?@..AB;;)
8?@.?BC;
else if (8?@G$num $ ?BCG$num)
&
?BCG$si9.8?@;
8?@.?BC;
1
else
&
6.7.8?@;
J#ile (6G$num ! ?BCG$num -- 6M.AB;;)
&
if (6..8?@) 6.6G$si9;
else
&
6.6G$si9;
7.7G$si9;
1
1
?BCG$si9.7G$si9;
7G$si9.?BC;
1
1
%oid e=traer(%oid)
&
int %ar;
if (8?@..AB;;) return;
clrscr( );
printf():ntroduce el nRmero a e=traer+ ));
scanf(),d)(-%ar);
if (8?@G$num..%ar)
&
6.8?@;
8?@.8?@G$si9;
free(6);
1
else
&
6.7.8?@;
J#ile (6G$num M. %ar -- 6M.AB;;)
&
if (6..8?@) 6.6G$si9;
else
&
6.6G$si9;
7.7G$si9;
1
1
if (6..AB;;) return;
7G$si9.6G$si9;
free(6);
1
1
%oid %isualizar(%oid)
&
if (8?@..AB;;) return;
clrscr( );
?BC.8?@;
J#ile (?BCM.AB;;)
&
printf()ARmero+ ,d2n)(?BCG$num);
?BC.?BCG$si9;
1
9etc#( );
1
"a estructura que utilizaremos ser#
struct lista
&
tipo %ariables;
struct lista 'si9;
1'8?@.AB;;('?BC.AB;;('7.AB;;('6.AB;;;
donde tipo %ariables sern las variales que guardaremos en la estructura, struct
lista 'si9 es un puntero que apunta al elemento de tipo lista introducido a continuacin,
'8?@ ser donde guardaremos el primer elemento de la lista, '?BC nos servir para
guardar elementos temporalmente y para recorrer la lista al visualizarla, '6 para
comparar los valores introducidos y ordenarlos, y '7, que apuntar al elemento anterior
al 3ltimo introducido.
.ntes de insertar un elemento, deeremos comproar si la lista est vac/a o no. Si lo
est deeremos insertar el primer elemento#
if (8?@..AB;;) 8?@.?BC;
Si ya e+istiera alg3n elemento haremos que 6 y 7 apunten al primero de la lista. Si el
elemento introducido fuera menor que el primero de la lista, har/amos que el nuevo
elemento pasara a ser el primero, y el que hasta ahora era el primero, pasar/a a ser el
segundo.
if (?BCG$num ! 8?@G$num)&
?BCG$si9.8?@;
8?@.?BC;
1
&ara e+traer un elemento de la lista solicitaremos un n3mero, si el n3mero
introducido se corresponde con el campo num de uno de los elementos, 4ste ser
e+tra/do de la lista. ;eeremos controlar que la lista no est4 vac/a y que el elemento con
el n3mero solicitado e+ista.
</jate en el ejemplo, en la funcin e+traer. Si 8?@ es igual a AB;;, ser que la lista
est vac/a, y si 6 es igual a AB;; al salir del J#ile significar que no se ha encontrado
ning3n elemento que contenga el n3mero introducido.
&ara visualizar la lista comproaremos que e+istan elementos, es decir, que 8?@ sea
distinto de AB;;. Hecho esto asignaremos a ?BC la direccin de 8?@ e iremos
recorriendo la lista mientras ?BC sea distinto de AB;;.
if (8?@..AB;;) return;
?BC.8?@;
J#ile(?BCM.AB;;)
&
printf(),d)(?BCG$num);
?BC.?BCG$si9;
1
Estructura grfica de una lista#
.qu/ finaliza el tema de la gestin dinmica de memoria. Es un tema algo complejo
hasta que se asimila el concepto y funcionamiento de las diferentes estructuras, pero tras
conseguirlo ya no tiene ning3n secreto. Si alguna vez no recuerdas su funcionamiento
siempre es una uena solucin coger papel y lpiz, diujar una pila, cola o lista
grficamente y simular la introduccin de elementos, escriiendo la situacin de los
punteros en cada momento.
E+isten otras estructuras, como las listas circulares y las listas doblemente
enlazadas. "a 3nica diferencia con la lista que conocemos es que en las primeras el
puntero final enlaza al nodo inicial y con la segunda que cada elemento guarda la
direccin del nodo anterior y del posterior, dando una estructura del tipo#
struct lista_doble
&
c#ar nombre[>/];
struct lista_doble 'ant;
struct lista_doble 'si9;
1;
Su funcionamiento es muy similar al de una lista normal.
=tras estructuras, como los rboles son ms complejas y menos utilizadas.

Potrebbero piacerti anche