Está en la página 1de 11

La memoria dinmica se refiere a aquella memoria que no puede ser definida ya que

no se conoce o no se tiene idea del nmero de la variable a considerarse, la solucin a


este problema es la memoria dinmica que permite solicitar memoria en tiempo de
ejecucin, por lo que cuanta ms memoria se necesite, ms se solicita al sistema
operativo. El sistema operativo maneja la memoria gracias al uso de punteros, por la
misma naturaleza del proceso nos impide conocer el tamao de la memoria necesaria
en el momento de compilar.

Un dato importante es que como tal este tipo de datos se crean y se destruyen mientras
se ejecuta el programa y por lo tanto la estructura de datos se va dimensionando de
forma precisa a los requerimientos del programa, evitndonos as perder datos o
desperdiciar memoria si hubiramos tratado de definir la cantidad de memoria a utilizar
en el momento de compilar el programa.

Cuando se crea un programa en el que es necesario manejar memoria dinmica el


sistema operativo divide el programa en cuatro partes que son: texto, datos
(estticos), pila y una zona libre o heap. En la ltima parte es donde queda la memoria
libre para poder utilizarla de forma dinmica. En el momento de la ejecucin habr tanto
partes libres como partes asignadas al proceso por lo cual si no se liberan las partes
utilizadas de la memoria y que han quedado inservibles es posible que se agote esta
parte y por lo tanto la fuente de la memoria dinmica. Tambin la pila cambia su tamao
dinmicamente, pero esto no depende del programador sino del sistema operativo.

MEMORIA DINMICA
La memoria dinmica es un espacio de almacenamiento que se solicita en tiempo
de ejecucin. De esa manera, a medida que el proceso va necesitando espacio para
ms lneas, va solicitando ms memoria al sistema operativo para guardarlas. El
medio para manejar la memoria que otorga el sistema operativo, es el puntero,
puesto que no podemos saber en tiempo de compilacin dnde nos dar huecos el
sistema operativo (en la memoria de nuestro PC).
Un dato importante es que como tal este tipo de datos se crean y se destruyen
mientras se ejecuta el programa y por lo tanto la estructura de datos se va
dimensionando de forma precisa a los requerimientos del programa, evitndonos as
perder datos o desperdiciar memoria si hubiramos tratado de definirla cantidad de
memoria a utilizar en el momento de compilar el programa.
Cuando se crea un programa en el que es necesario manejar memoria dinmica el
sistema operativo divide el programa en cuatro partes que son: texto, datos
(estticos), pila y una zona libre o heap. En el momento de la ejecucin habr tanto
partes libres como partes asignadas al proceso por lo cual si no se liberan las partes
utilizadas de la memoria y que han quedado inservibles es posible que se agote
esta parte y por lo tanto la fuente de la memoria dinmica. Tambin la pila cambia su
tamao dinmicamente, pero esto no depende del programador sino del sistema
operativo.
VENTAJAS:
Es posible disponer de un espacio de memoria arbitrario que dependa de
informacin dinmica (disponible slo en ejecucin): Toda esa memoria que maneja
es implementada por el programador cuando fuese necesario.
Otra ventaja de la memoria dinmica es que se puede ir incrementando durante la
ejecucin del programa. Esto permite, por ejemplo, trabajar con arreglos dinmicos.
Es memoria que se reserva en tiempo de ejecucin. Su tamao puede variar durante
la ejecucin del programa y puede ser liberado mediante la funcin free.

DESVENTAJAS:
Es difcil de implementar en el desarrollo de un programa o aplicacin.
Es difcil implementar estructuras de datos complejas como son los tipos recursivos
(rboles, grafos, etc.).Por ello necesitamos una forma para solicitar y liberar
memoria para nuevas variables que puedan ser necesarias durante la ejecucin de
nuestros programas: Heap.
Una desventaja de la memoria dinmica es que es ms difcil de manejar.
La memoria dinmica puede afectar el rendimiento. Puesto que con la memoria
esttica el tamao de las variables se conoce en tiempo de compilacin, esta
informacin est incluida en el cdigo objeto generado. Cuando se reserva memoria
de manera dinmica,
Se tienen que llevar a cabo varias tareas, como buscar un bloque de memoria libre y
almacenar la posicin y tamao de la memoria asignada, de manera que pueda ser
liberada ms adelante. Todo esto representa una carga adicional, aunque esto
depende de la implementacin y hay tcnicas para reducir su impacto.

Programacin en C/Manejo
dinmico de memoria
< Programacin en C

Seguramente durante todo tu recorrido con este libro, especialmente en la seccin de


punteros, te hablbamos sobre la asignacin dinmica de memoria. Como su nombre lo
dice, este es una forma de conseguir espacio en memoria, dndote mas eficiencia y
tcnicamente hacer lo que requieras hacer con este.

En esta seccin haremos uso bastante (inevitablemente) de los punteros, por lo que te
recomendamos que tengas muy bien establecidos estos conocimientos.

Memoria dinmica[editar]

Es memoria que se reserva en tiempo de ejecucin. Su principal ventaja frente a la


esttica, es que su tamao puede variar durante la ejecucin del programa. (En C, el
programador es encargado de liberar esta memoria cuando no la utilice ms). El uso de
memoria dinmica es necesario cuando a priori no conocemos el nmero de
datos/elementos a tratar.

Memoria esttica[editar]
Es el espacio en memoria que se crea al declarar variables de cualquier tipo de dato
(primitivas [int,char...] o derivados [struct,matrices,punteros...]). La memoria que estas
variables ocupan no puede cambiarse durante la ejecucin y tampoco puede ser
liberada manualmente.

Diferencias, ventajas y desventajas[editar]

La memoria reservada de forma dinmica suele estar alojada en el heap o


almacenamiento libre, y la memoria esttica en el stack o pila (con excepcin de los
objetos de duracin esttica, que se vern ms adelante, los cuales normalmente se
colocan en una zona esttica de datos). La pila generalmente es una zona muy limitada.
El heap, en cambio, en principio podra estar limitado por la cantidad de memoria
disponible durante la ejecucin del programa y el mximo de memoria que el sistema
operativo permita direccionar a un proceso. La pila puede crecer de forma dinmica,
pero esto depende del sistema operativo. En cualquier caso, lo nico que se puede
asumir es que muy probablemente dispondremos de menor espacio en la pila que en el
heap.

Otra ventaja de la memoria dinmica es que se puede ir incrementando durante la


ejecucin del programa. Esto permite, por ejemplo, trabajar con arreglos dinmicos.
Aunque en C, a partir del estndar C99 se permite la creacin de arreglos cuyo tamao
se determina en tiempo de ejecucin, no todos los compiladores implementan este
estndar. Adems, se sigue teniendo la limitante de que su tamao no puede cambiar
una vez que se especifica, cosa que s se puede lograr asignando memoria de forma
dinmica.

Una desventaja de la memoria dinmica es que es ms difcil de manejar. La memoria


esttica tiene una duracin fija, que se reserva y libera de forma automtica. En
contraste, la memoria dinmica se reserva de forma explcita y contina existiendo hasta
que sea liberada, generalmente por parte del programador.

La memoria dinmica puede afectar el rendimiento. Puesto que con la memoria esttica
el tamao de las variables se conoce en tiempo de compilacin, esta informacin est
incluida en el cdigo objeto generado, por lo cual el proceso es muy eficiente. Cuando
se reserva memoria de manera dinmica, se tienen que llevar a cabo varias tareas,
como buscar un bloque de memoria libre y almacenar la posicin y tamao de la
memoria asignada, de manera que pueda ser liberada ms adelante. Todo esto
representa una carga adicional, aunque esto depende de la implementacin y hay
tcnicas para reducir su impacto.

El lenguaje C y el manejo de la memoria[editar]

Todos los objetos tienen un tiempo de vida, es decir, el tiempo durante el cual se
garantiza que el objeto exista. En C, existen 3 tipos de duracin: esttica, automtica y
asignada. Las variables globales y las variables locales declaradas con el
especificador static tienen duracin esttica. Se crean antes de que el programa
inicie su ejecucin y se destruyen cuando el programa termina. Las variables locales
no static tienen duracin automtica. Se crean al entrar al bloque en el que fueron
declaradas y se destruyen al salir de ese bloque. Duracin asignada se refiere a los
objetos cuya memoria se reserva de forma dinmica. Como se explic anteriormente,
esta memoria se crea y se debe liberar de forma explcita. Los arreglos de longitud
variable de C99 son un caso especial. Tienen duracin automtica, con la particularidad
de que son creados a partir de su declaracin.

La biblioteca estndar de C proporciona las funciones malloc, calloc,


realloc y free para el manejo de memoria dinmica. Estas funciones estn definidas
en el archivo de cabecera stdlib.h .

malloc[editar]
La funcin malloc reserva un bloque de memoria y devuelve un puntero void al inicio
de la misma. Tiene la siguiente definicin:

void *malloc(size_t size);

donde el parmetro size especifica el nmero de bytes a reservar. En caso de que no


se pueda realizar la asignacin, devuelve el valor nulo (definido en la macro NULL ), lo
que permite saber si hubo errores en la asignacin de memoria.

Ej:

int *puntero;

char *puntcarc;

puntero=(int *)malloc(4);

puntcarc=(char *)malloc(200);

A continuacin se muestra un ejemplo de su uso:

int *i;

/* Reservamos la memoria suficiente para almacenar un int y


asignamos su direccin a i */

i = malloc(sizeof(int));

/* Verificamos que la asignacin se haya realizado correctamente */


if (i == NULL) {
/* Error al intentar reservar memoria */
}

Uno de los usos ms comunes de la memoria dinmica es la creacin de vectores cuyo


nmero de elementos se define en tiempo de ejecucin:

int *vect1, n;
printf("Nmero de elementos del vector: ");
scanf("%d", &n);

/* reservar memoria para almacenar n enteros */


vect1 = malloc(n * sizeof(int));

/* Verificamos que la asignacin se haya realizado correctamente */


if (vect1 == NULL) {
/* Error al intentar reservar memoria */
}

calloc[editar]
La funcin calloc funciona de modo similar a malloc , pero adems de reservar
memoria, inicializa a 0 la memoria reservada. Se usa comnmente para arreglos y
matrices. Est definida de esta forma:

void *calloc(size_t nmemb, size_t size);

El parmetro nmemb indica el nmero de elementos a reservar, y size el tamao de


cada elemento. El ejemplo anterior se podra reescribir con calloc de esta forma:
int *vect1, n;
printf("Nmero de elementos del vector: ");
scanf("%d", &n);

/* Reservar memoria para almacenar n enteros */


vect1 = calloc(n, sizeof(int));

/* Verificamos que la asignacin se haya realizado correctamente */


if (vect1 == NULL) {
/* Error al intentar reservar memoria */
}

realloc[editar]
La funcin realloc redimensiona el espacio asignado de forma dinmica anteriormente a
un puntero. Tiene la siguiente definicin:

void *realloc(void *ptr, size_t size);

Donde ptr es el puntero a redimensionar, y size el nuevo tamao, en bytes, que


tendr. Si el puntero que se le pasa tiene el valor nulo, esta funcin acta
como malloc . Si la reasignacin no se pudo hacer con xito, devuelve un puntero nulo,
dejando intacto el puntero que se pasa por parmetro. Al usar realloc , se debera
usar un puntero temporal. De lo contrario, podramos tener una fuga de memoria, si es
que ocurriera un error en realloc .

Ejemplo de realloc usando puntero temporal:

/* Reservamos 5 bytes */
void *ptr = malloc(5);

/* Redimensionamos el puntero (a 10 bytes) y lo asignamos a un


puntero temporal */
void *tmp_ptr = realloc(ptr, 10);

if (tmp_ptr == NULL) {
/* Error: tomar medidas necesarias */
}
else {
/* Reasignacin exitosa. Asignar memoria a ptr */
ptr = tmp_ptr;
}

Cuando se redimensiona la memoria con realloc , si el nuevo tamao


(parmetro size ) es mayor que el anterior, se conservan todos los valores originales,
quedando los bytes restantes sin inicializar. Si el nuevo tamao es menor, se conservan
los valores de los primeros size bytes. Los restantes tambin se dejan intactos, pero
no son parte del bloque regresado por la funcin.

free o cfree[editar]
La funcin free sirve para liberar memoria que se asign dinmicamente. Si el puntero
es nulo, free no hace nada. Adems existe la funcin cfree, que sirve para liberar
memoria de los elementos que han sido reservados con calloc(). Tienen la siguiente
definicin:

void free(void *ptr); void cfree (void *ptr);

El parmetro ptr es el puntero a la memoria que se desea liberar:

int *i;
i = malloc(sizeof(int));

free(i);

Una vez liberada la memoria, si se quiere volver a utilizar el puntero, primero se debe
reservar nueva memoria con malloc o calloc :

int *i = malloc(sizeof(int));

free(i);

/* Reutilizamos i, ahora para reservar memoria para dos enteros */


i = malloc(2 * sizeof(int));

/* Volvemos a liberar la memoria cuando ya no la necesitamos */
free(i);

Buenas prcticas[editar]

Como se vio en las secciones anteriores, siempre que se reserve memoria de forma
dinmica con malloc , realloc o calloc , se debe verificar que no haya habido
errores (verificando que el puntero no sea NULL ). Cuando se trata de verificar el valor
de un puntero (y slo en ese caso), se puede usar de forma indistinta 0 NULL . Usar
uno u otro es cuestin de estilo. Como ya se vio, las funciones de asignacin dinmica
de memoria devuelven un puntero void . Las reglas de C establecen que un
puntero void se puede convertir automticamente a un puntero de cualquier otro tipo,
por lo que no es necesario hacer una conversin (cast), como en el siguiente ejemplo:

/* El puntero void devuelto por malloc es convertido explcitamente


a puntero int */
int *i = (int *)malloc(sizeof(int));

Aunque no hay un consenso, muchos programadores prefieren omitir la conversin


anterior porque la consideran menos segura. Si accidentalmente se olvida incluir el
archivo stdlib.h (donde estn definidas malloc , calloc , realloc y free ) en un
programa que use dichas funciones, el comportamiento puede quedar indefinido. Si
omitimos la conversin explcita, el compilador lanzar una advertencia. Si, en cambio,
realizamos la conversin, el compilador generar el cdigo objeto de forma normal,
ocultado el bug.

Una posible razn para usar la conversin explcita es si se escribe cdigo en C que se
vaya a compilar junto con cdigo C++, ya que en C++ s es necesario realizar esa
conversin.

En cualquier caso, dado que el manejo de memoria es un tema complejo, y ste es un


error muy comn, se debe hacer nfasis en que cuando se trabaja con memoria
dinmica, siempre se debe verificar que se incluya el archivo stdlib.h .

Tratar de utilizar un puntero cuyo bloque de memoria ha sido liberado con free puede
ser sumamente peligroso. El comportamiento del programa queda indefinido: puede
terminar de forma inesperada, sobrescribir otros datos y provocar problemas de
seguridad. Liberar un puntero que ya ha sido liberado tambin es fuente de errores.
Para evitar estos problemas, se recomienda que despus de liberar un puntero siempre
se establezca su valor a NULL .

int *i;
i = malloc(sizeof(int));

free(i);
i = NULL;
-

También podría gustarte