Memoria Dinamica
Enviado por kamilik26 • 18 de Abril de 2013 • 2.113 Palabras (9 Páginas) • 562 Visitas
MEMORIA DINÁMICA
Es la memoria que se le asigna a una variable y le pertenece a ésta hasta que se termina la ejecución del programa.
La memoria dinámica, más que un tipo de memoria es una manera de utilizarla. Consiste en declarar variables y eliminarlas cuando ya no sean necesarias, mediante subprogramas. Es un espacio de almacenamiento que se puede solicitar en tiempo de ejecución. Además de solicitar espacios de almacenamiento, también podemos liberarlos (en tiempo de ejecución) cuando dejemos de necesitarlos.
Supongamos que nuestro programa debe manipular estructuras de datos de longitud desconocida. Un ejemplo simple podría ser el de un programa que lee las líneas de un archivo y las ordena. Por tanto, deberemos leer un número indeterminado de líneas, y tras leer la última, ordenarlas. Una manera de manejar ese “número indeterminado”, sería declarar una constante MAX_LINEAS, darle un valor grande, y declarar un array de tamaño MAX_LINEAS. Esto, obviamente, es muy ineficiente. Nuestro programa no sólo quedaría limitado por ese valor máximo, sino que además gastaría esa enorme cantidad de memoria para procesar hasta el más pequeño de los ficheros. La solución consiste en utilizar memoria dinámica. Esto conlleva que, a medida que el proceso va necesitando espacio para más líneas, va solicitando más memoria al sistema operativo para guardarlas.
UTILIZACIÓN DE MEMORIA DINÁMICA
Como sabemos, en lenguaje C/C++, &x es la dirección donde se almacena en memoria la variable x. Si p es un apuntador en C/C++, *p es el contenido de la localidad de memoria p. Si usamos C/C++ para implementar listas ligadas, podemos usar estos apuntadores. Sin embargo, primero analizaremos cómo asignar y liberar el almacenamiento en forma dinámica y cómo se accede al almacenamiento dinámico en C/C++.
• En C/C++, una variable que debe contener la dirección en la memoria que almacena un número entero se crea mediante la declaración.
int *p;
Recordemos que esta declaración se divide en dos partes: la parte de tipo int *, que indica que se trata de un apuntador a un entero; y la parte de identificador, en este caso p.
• Una vez declarada la variable p como un apuntador a un tipo específico de dato, debe ser posible crear dinámicamente un objeto de este tipo específico y asignar su dirección a p. Esto se hace en C/C++ mediante la función de la biblioteca estándar malloc (size). La función malloc asigna de manera dinámica una parte de memoria de tamaño especificado en size y devuelve un apuntador a un elemento de tipo char. Consideremos las siguientes declaraciones.
extern char *malloc ( );
int *pi;
float *pr;
La palabra clave extern especifica que una variable o función tiene un enlace externo. Esto significa que la variable o función a la que nos referimos está definida en algún otro archivo fuente, o más adelante en el mismo archivo. Sin embargo, en C/C++ podemos usar esta palabra clave extern con una cadena. La cadena indica que se está usando el convenio de enlace de otro lenguaje para los identificadores que se están definiendo. Para los programas C++ la cadena por defecto es “C++”.
• Los enunciados:
pi = (int *) malloc (sizeof (int));
pr = (float *) malloc (sizeof (float));
Crean directamente la variable entera *pi y la variable real *pr. Estas se denominan variables dinámicas. Al ejecutar estos enunciados, el operador sizeof devuelve el tamaño en bytes de su operando. Esto se usa para conservar la independencia de máquina. Después, malloc crea un objeto de este tamaño. Por tanto, malloc(sizeof(int)) asigna almacenamiento para un entero, en tanto que malloc(sizeof(float)) asigna espacio necesario para un real. De igual manera, malloc devuelve un apuntador al almacenamiento que asigna. Este apuntador es al primer byte de este almacenamiento y es de tipo char *. Para obligar al apuntador a que señale a un entero, usamos el operador de cálculo (int *) ó (float *).
• El operador sizeof, devuelve un valor de tipo int, en tanto que la función malloc espera un parámetro de tipo unsigned. Para hacer que correspondan, debemos escribir:
pi = (int * ) malloc ((unsigned)(sizeof (int)));
Como ejemplo, vamos a considerar este breve código:
#include <iostream>
int main (int argc, char * const argv [ ])
{
(1) int *p, *q;
(2) int x;
(3) p = (int *) malloc (sizeof (int));
(4) *p = 3;
(5) q = p;
(6) std::cout<< *p << " " << *q << "\n";
(7) x = 7;
(8) *q = x;
(9) std::cout<< *p << " " << *q << "\n";
(10) p = (int *) malloc (sizeof (int));
(11) *p = 5;
(12) std::cout<< *p << " " << *q << "\n";
return 0;
}
• En la línea (3), se crea una variable de tipo entero y su dirección se coloca en p. La línea (4) establece el valor de esa variable en 3. La línea (5) hace que la dirección q sea la misma dirección que p. El enunciado de la línea (5) es perfectamente válido, pues se asigna a una variable de tipo apuntador (q) el valor de otra variable del mismo tipo (p). En este momento *p y *q hacen referencia a la misma variable. Por tanto, la línea (6) imprime el contenido de esa variable (que ahora es 3) dos veces.
• En la línea (7), se almacena el valor 7 en la variable entera x. La línea (8) cambia el valor de *q al valor de x. sin embargo, dado que p y q apuntan a la misma variable, *p y *q tienen el valor 7. Por tanto la línea (9) imprime el número 7 dos veces.
• La línea (10) crea una nueva variable entera y coloca su dirección en p. Ahora *p hace referencia a la variable entera recién creada que todavía no ha recibido un valor. q no ha cambiado; por lo que el valor de *q sigue siendo 7. Observemos que *p no hace referencia a una variable específica única. Su valor cambia conforme se modifica el valor de p. La línea (11) establece el valor de esta variable recién creada en 5 y la línea 12 imprime los valores 5 y 7. Y así la salida del programa es:
3 3
7 7
5 7
mallocEjemplo has exited with status 0.
• La función free se usa en C para liberar almacenamiento de una variable asignada dinámicamente. La orden:
free (p);
Invalida
...