1 MANEJO DINÁMICO DE MEMORIA - Departamento de Informática

Anuncio
Universidad Técnica Federico Santa María
EX UMBRA
IN
Departamento de Informática
Prof. Hubert Hoffmann N.
SOLEM
MANEJO DINÁMICO DE MEMORIA
Se distinguen dos tipos de variables: estáticas y dinámicas. A las variables estáticas se le
asigna el espacio que necesitan en la memoria antes de la ejecución de una función o programa.
El espacio que ocupa una variable dinámica es asignado y liberado según las necesidades
mientras se ejecuta la función o el programa.
El espacio en la memoria que ocupa una variable estática es referenciado, es decir a este
espacio hay acceso a través de un nombre declarado por el programador y en el caso de una
variable dinámica es referenciado por medio de un puntero.
Los punteros son un tipo de datos especial que se distingue de los demás tipos de datos ya que
permite almacenar referencias a la memoria. Estas referencias o direcciones se denominan en
los diferentes lenguajes de programación generalmente punteros (pointer).
El tipo de datos puntero permite el manejo dinámico de memoria:
 A través de una variable se puede reservar el espacio en la memoria que se necesite.
 Una cantidad de memoria no predefinida se puede manejar en forma simple: se
pueden añadir, insertar y eliminar elementos.
Una variable p del tipo puntero tiene como valor una referencia (puntero, dirección) a un objeto
del llamado tipo referenciado. Este objeto referenciado será creado en el tiempo de ejecución en
C++ por el operador new. Este objeto referenciado no es declarado, pero la variable del tipo
puntero si lo es: El puntero es una variable estática, mientras el objeto referenciado es un
elemento dinámico (Figura 1).
p
Objeto
Referenciado
Figura 1: Puntero - Pointer
El objeto referenciado no es directamente identificado por el nombre de una variable, sino a
través del nombre de una variable del tipo “puntero-a-tipo”.
El operador new es un operador unario que permite asignar espacio de memoria para una
instancia de un tipo de datos específico en tiempo de ejecución. El operador requiere como
argumento el nombre del tipo de datos y retorna un puntero al espacio asignado.
Se declara en C++
int *p, n=5, k;
En este caso, p es una variable “puntero al tipo int”. Se puede almacenar la dirección de la
variable n en p escribiendo
p = &n;
En este ejemplo, *p denota un objeto del tipo int en la memoria, *p es el mismo espacio que
ocupa la variable n en la memoria. Después de ejecutar la asignación p=&n;, el objeto al cual
apunta p resulta ser la variable n del tipo int. Después de almacenar la dirección de n en p, es
posible tratar *p como otra expresión para n.
Si se continúa con
k = *p;
entonces el valor de k será 5, igual si se hubiese escrito
420304994.doc
1
13-11-15
Universidad Técnica Federico Santa María
EX UMBRA
IN
Departamento de Informática
Prof. Hubert Hoffmann N.
SOLEM
k = n;.
El proceso para obtener el valor 5 utilizando p se denomina dereferenciación o indirección y el
operador unario * en *p es el operador de dereferenciación o indirección.
Hay que distinguir cuidadosamente entre p y *p. La variable p es del tipo “puntero-a-int” y por
eso se pueden asignar a ella direcciones, mientras que a *p se puede asignar valores enteros ya
que es una expresión del tipo int. *p no se debe utilizar antes de haber asignado un valor a p. En
este caso la variable p es indefinida.
Con la siguiente función se demuestra este error:
int main()
{
char *p, ch;
*p = ‘A’;
return 0;
// ERROR
}
Este error se puede corregir agregando p = &ch; antes de la asignación *p = ‘A’; Ahora se
asigna ‘A’ a la variable ch, es decir a *p.
Un puntero puede apuntar también a ninguna celda de la memoria. En este caso, tiene el valor
NULL. Esto significa que un puntero puede

apuntar a una celda de la memoria,

tener el valor NULL (no apuntar a ninguna celda) o

ser indefinido (generalmente un error).
Para alocar espacio en la memoria dinámicamente, es decir en el tiempo de ejecución, se utiliza
el operador new. En C se utiliza la función malloc (p = (int *) malloc(1)).
int *p;
p = new int;
En este caso se alocó espacio en la memoria para un solo valor del tipo int.
Ejemplo: Puntero a una estructura (struct)
struct oficina
{
int numero;
int tamaño;
int fono;
};
oficina o1, o2, *op1, *op2;
Acceso a los campos es:
o1.numero=56;
o2.fono=123456;
(*op1).numero=56;
(*op1).fono=o2.fono; Se escribe también: op1->fono=o2.fono;
Otras estructuras son:
struct oficina1
{
int numero;
420304994.doc
2
13-11-15
Universidad Técnica Federico Santa María
EX UMBRA
IN
Departamento de Informática
Prof. Hubert Hoffmann N.
SOLEM
int tamano;
int fono;
persona *profesor;
};
struct oficina2
{
int numero, tamano, fono;
oficina2 *siguiente;
};
El espacio reservado en la memoria a través de new se puede liberar a través de delete.

Ejemplo: int *p = new int; delete p;

Pero no se puede hacer lo siguiente:
int
a = 5;
int
*p = &a;
delete p;
420304994.doc
// p no apunta a algo reservado a través de new
3
13-11-15
Descargar