C++ cap 11

Tema 11 - Asignación dinámica de memoria.
Antes de empezar con el desarrollo del tema, es necesario aclarar que el mismo
no pretende explicar las estructuras de datos dinámicas, sino tan solo dar unas ligeras
nociones básicas sobre la posibilidad de asignar memoria de forma dinámica, esto es,
en tiempo de ejecución, y por tanto de crear nuevas variables.
Las  funciones  que  realizan  un  manejo  activo  de  la  memoria  del  sistema
requieren  todas  ellas  para  su  correcto  funcionamiento  la  inclusión,  mediante  la
directiva del prepocesador #include del archivo de cabecera <stdlib.h>.
11.1 - Reserva dinámica de memoria.
En C, la reserva dinámica de memoria se realiza mediante el uso de funciones,
existen  varias  funciones  de  reserva  de  memoria  (ver  apéndice  A),  pero  aquí  solo
explicaremos la reserva dinámica de memoria mediante la función malloc(). La función
malloc() tiene la forma:
void *malloc(unsigned num_bytes);
Siendo  num_bytes el  número  de  bytes  que  se  desean  reservar.  La  función
malloc() devuelve un puntero al tipo de datos void (sin tipo). Dicho puntero puede ser
asignado  a  una  variable  puntero  de  cualquier  tipo  base  mediante  una  conversión
forzada de tipo de datos (casts). Veamos un ejemplo:
int *a;
a=(int *)malloc(sizeof(int));
Y ahora podríamos realizar la siguiente asignación:
*a=3;
La función  malloc(),  y en general,  cualquier  función de reserva dinámica de
memoria,  devuelve  un  puntero  nulo  (NULL)  si  la  reserva  de  memoria  no  puede
realizarse,  generalmente por falta  de memoria disponible.  Por  ello,  antes de usar  un
puntero  devuelto  por  la  función  malloc() o por  cualquier  otra  función de  reserva
dinámica  de  memoria  es  imprescindible,  con el  fin de  evitar  posibles  fallos  en la
ejecución del  programa,  comprobar  que dicho puntero no es nulo (NULL).  Veamos
algunos ejemplos de reserva dinámica de memoria:
float *a;
a=(float *)malloc(sizeof(float));
if (a==NULL) exit(0); /* Salimos del programa */
unsigned long int*b;
if ((b=(unsigned long int)malloc(sizeof(unsigned long int)))==NULL)
   exit(0); /* Salimos del programa */
struct ALFA{El lenguaje de programación C
   unsigned a;
float b;
int *c;
}*d;
if ((d=(struct ALFA *)malloc(sizeof(struct ALFA)))==NULL)
exit(0); /Salimos del programa */
11.2 - Liberación dinámica de memoria.
La memoria dinámica reservada es eliminada siempre al terminar la ejecución
del programa por el propio sistema operativo. Sin embargo, durante la ejecución del
programa puede ser  interesante,  e incluso necesario,  proceder  a  liberar  parte  de la
memoria  reservada  con  anterioridad  y  que  ya  ha  dejado  de  ser  necesario  tener
reservada.  Esto puede realizarse mediante la función free(). La función free() tiene la
forma:
void free(void *p);
Donde p es la variable de tipo puntero cuya zona de memoria asignada de forma
dinámica queremos liberar. Veamos un ejemplo de liberación de memoria:
int *a;
if ((a=(int *)malloc(sizeof(int)))==NULL)
   exit(0); /* Salimos del programa */
......
free(a);
Un aspecto a tener en cuenta es el hecho de que el puntero a liberar no debe
apuntar a nulo (NULL), pues en tal caso se producirá un fallo en el programa. Es por
ello que cobra aún más sentido la necesidad de comprobar  al  reservar  memoria de
forma dinámica que la reserva se ha realizado de forma correcta, tal y como se explico
en el apartado anterior.
11.3  -  Ejemplo  de  asignación  y  liberación  dinámica  de
memoria.
Vamos a ver un sencillo ejemplo práctico de como asignar y liberar memoria.
Para ello construiremos las funciones necesarias para crear, manejar y liberar de forma
dinámica una lista ligada.
En primer  lugar,  definiremos la estructura  de datos  necesaria para  ello.  Esta
estructura de datos es:
struct LISTA{
   tipo dato;
   struct LISTA *sig;
};
Donde tipo es cualquier tipo de datos valido (float, int, long int, etc.)El lenguaje de programación C
Las variables necesarias para crear la lista son las siguientes:
struct LISTA *cabeza=NULL,*p;
tipo dato;
El código de la función de creación de la lista, con inserción por la cabeza:
struct LISTA *CrearLista(struct LISTA *cabeza,tipo dato)
{
   struct LISTA *p;
   if ((p=(struct LISTA *)malloc(sizeof(struct LISTA)))==NULL)
      exit(0); /* Salimos del programa */
   p->dato=dato;
   p->sig=cabeza;
   return p;
}
Siendo la llamada para la creación de la forma:
cabeza=CrearLista(cabeza,dato);
La función para obtener un elemento de la lista es:
struct LISTA *BuscarLista(struct LISTA *p,tipo dato)
{
   while (p!=NULL && p->dato!=dato)
      p=p->sig;
return p;
}
Siendo la llamada de la forma:
if ((p=BuscarLista(cabeza,dato))!=NULL)
   /* El elemento ha sido encontrado */
Y por último, la función para liberar un elemento de la memoria es:
struct LISTA *LiberarLista(struct LISTA *cabeza,tipo dato)
{
   struct LISTA p,q;
   if (cabeza!=NULL)
   {
      p=cabeza;
      if (cabeza->dato==dato)
         cabeza=cabeza->sig;
      else
         while (p!=NULL && p->dato!=dato)
{
            q=p;
p=p->sig;
}
      if (p!=NULL)
{El lenguaje de programación C
         q->sig=p->sig;
free(p);
      }
   }
return cabeza;
}
Siendo la llamada:
cabeza=LiberarLista(cabeza,dato);

No hay comentarios.:

Publicar un comentario

!!Clikeaka al espacio cideral!!

THEMRFRIKI S.A. Con tecnología de Blogger.

About