Tema 6: Memoria dinámica Programación 2 Notas Tema 6

Anuncio
Notas
Tema 6
Organización
de la memoria
Memoria estática
Tema 6: Memoria dinámica
Memoria dinámica
Punteros
Programación 2
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Curso 2014-2015
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Notas
Índice
Tema 6
Organización
de la memoria
1
2
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
3
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
4
Organización de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y declaración
Dirección y contenido
Declaración con inicialización
Ejercicios
Uso de punteros
Reserva y liberación de memoria
Punteros y vectores
Punteros definidos con typedef
Punteros y registros
Parámetros de funciones
Errores comunes
Ejercicios
Listas
Notas
Memoria estática
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
El tamaño es fijo y se conoce al implementar el
programa
Declaración de variables
int i=0;
char c;
float vf[3]={1.0, 2.0, 3.0};
Uso de
punteros
i
0
c
Punteros y vectores
vf[0]
1.0
vf[1]
2.0
vf[2]
3.0
Punteros definidos
con typedef
1000
1002
1004
1006
1008
Reserva y liberación
de memoria
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Notas
Memoria dinámica
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Normalmente se utiliza para almacenar grandes
volúmenes de datos, cuya cantidad exacta se
desconoce al implementar el programa
La cantidad de datos a almacenar se calcula durante la
ejecución del programa y puede cambiar
En C++ se puede hacer uso de la memoria dinámica
usando punteros
Notas
Definición y declaración
Tema 6
Organización
de la memoria
Memoria estática
Un puntero es un número (entero largo) que se
corresponde con una dirección de memoria
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
En la declaración de un puntero, se debe especificar el
tipo de dato que contiene la dirección de memoria
Se declaran usando el carácter *
Ejemplos:
int *punteroAEntero;
char *punteroAChar;
int *VectorPunterosAEntero[tVECTOR];
double **punteroAPunteroAReal;
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Notas
Dirección y contenido
Tema 6
Organización
de la memoria
Memoria estática
*x
&x
Contenido de la dirección apuntada por x
Dirección de memoria de la variable x
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Ejemplo:
int i=3;
int *pi;
pi=&i;
// pi=direccion de memoria de i
*pi = 11; // contenido de pi=11. Por lo tanto, i = 11
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
i
11
pi
1000
1000
1002
1004
1006
1008
Notas
Declaración con inicialización
Tema 6
Organización
de la memoria
Declaración con inicialización:
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
int *pi=&i;
// pi contiene la direccion de i
El puntero NULL es aquel que no apunta a ninguna
variable
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
int *pi=NULL;
Precaución: siempre que un puntero no tenga memoria
asignada debe valer NULL.
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Notas
Ejercicios
Tema 6
Organización
de la memoria
Ejercicio 1
Indica cuál sería la salida de los siguientes fragmentos de
código:
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
int e1;
int *p1, *p2;
e1 = 7;
p1 = &e1;
p2 = p1;
e1++;
(*p2) += e1;
cout << *p1;
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
int a=7;
int *p=&a;
int **pp=&p;
cout << **pp;
Notas
Reserva y liberación de memoria (1/2)
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Los punteros pueden usarse para reservar (con new) o
liberar (con delete) memoria dinámica
Ejemplo:
double *pd;
pd = new double;
*pd = 4.75;
cout << *pd << endl;
delete pd;
// reserva memoria
// muestra 4.75
// libera memoria
Uso de
punteros
Punteros y vectores
pd
2000
Punteros definidos
con typedef
1000
Reserva y liberación
de memoria
4.75
1002
...
2000
2002
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Ojo: Las variables locales y las reservadas con new
van a zonas de memoria distintas.
Listas
Notas
Reserva y liberación de memoria (2/2)
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Cuando se usa new, el compilador reserva memoria y
devuelve la dirección de inicio de ese espacio
reservado
Si no hay suficiente memoria para la reserva, new
devuelve NULL
Siempre que se reserva memoria con new hay que
liberarla con delete
Ojo: Tras hacer delete, el puntero no vale NULL por
defecto
Un puntero se puede reutilizar; tras liberar su contenido
se puede reservar memoria otra vez con new
Notas
Punteros y vectores (1/2)
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Los punteros también pueden usarse para crear
vectores o matrices
Para reservar memoria hay que usar corchetes y
especificar el tamaño
Para liberar toda la memoria reservada es necesario
usar corchetes
Ejemplo:
int *pv;
int n=10;
pv=new int[n]; // reserva memoria para n enteros
pv[0]=585; // usamos el puntero como si fuera un vector
delete [] pv; // liberar la memoria reservada
Errores comunes
Ejercicios
Listas
Notas
Punteros y vectores (2/2)
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Los punteros se pueden usar como accesos directos a
componentes de vectores o matrices
Ejemplo:
int v[tVECTOR];
int *pv;
pv = &(v[7]);
*pv = 117; // v[7] = 117;
Notas
Punteros definidos con typedef
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Se pueden definir nuevos tipos de datos con typedef:
typedef int entero; // entero es un tipo, como int
entero a,b; // int a,b;
Para facilitar la claridad en el código, suelen definirse
los punteros con typedef:
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
typedef int *punteroAEntero;
typedef struct {
char c;
int i;
} Registro, *PunteroRegistro;
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Notas
Punteros y registros
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Cuando un puntero referencia a un registro, se puede
usar el operador -> para acceder a sus campos
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
typedef struct {
char c;
int i;
} Registro, *PunteroRegistro;
PunteroRegistro pr;
pr = new Registro;
pr->c = ’a’; // (*pr).c = ’a’;
Notas
Parámetros de funciones (1/2)
Tema 6
Paso de parámetros a funciones
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
void f (int *p) {
*p=2;
}
// Por valor
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
void f2 (int *&p) { // Por referencia
int num=10;
p=#
}
int main() {
int i=0;
int *p=&i;
f(p);
// Llamada a funciones
f2(p);
}
Errores comunes
Ejercicios
Listas
Notas
Parámetros de funciones (2/2)
Tema 6
Paso de parámetros a funciones usando typedef
Organización
de la memoria
typedef int* PInt;
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
void f (PInt p){
*p=2;
}
// Por valor
void f2 (PInt &p) { // Por referencia
int num=10;
p=#
}
int main() {
int i=0;
PInt p=&i;
f(p);
// Llamada a funciones
f2(p);
}
Notas
Errores comunes
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Utilizar un puntero sin haberle asignado memoria o
apuntando a nada
int *pEntero;
*pEntero = 7; // Error !!!
Usar un puntero tras haberlo liberado
punteroREGISTRO p,q;
p = new REGISTRO;
...
q = p;
delete p;
q->num =7; // Error !!!
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Liberar memoria no reservada
int *p=&i;
delete p;
Listas
Notas
Ejercicios
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicio 2
Dado el siguiente registro:
typedef struct {
char nombre[32];
int edad;
} Cliente;
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
Realizar un programa que lea un cliente (sólo uno) de
un fichero binario, lo almacene en memoria dinámica
usando un puntero, imprima su contenido y finalmente
libere la memoria reservada.
Notas
Listas: Definición
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Se utilizan para almacenar un número variable de
objetos
Cada objeto se almacena en un nodo, que se enlaza
con el siguiente
La lista es un puntero al primer nodo, o NULL si está
vacía
Un nodo es un contenedor para almacenar
información, y tiene dos partes:
El objeto que se desea guardar
Uno o más punteros para enlazar el nodo con otros
nodos y construir la estructura de datos.
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Objeto
Errores comunes
Ejercicios
Listas
Notas
Listas: Implementación en C++
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
typedef struct {
char c;
// informacion de cada objeto
...
} Objeto;
typedef struct tNodo {
Objeto obj; // el objeto o dato a almacenar
struct tNodo *pSig; // enlace con el siguiente
} Nodo, *pNodo, *Lista;
// Lista = pNodo = Nodo * =
tNodo *
// declaracion de la lista (dentro de una funcion)
Lista li = NULL;
Notas
Operaciones básicas con listas (1/5)
Tema 6
Ver si la lista está vacía
Organización
de la memoria
bool esVacia(Lista li)
{
return (li == NULL);
}
Memoria estática
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Crear un nuevo nodo que contiene un objeto:
pNodo crearNodo(const Objeto &o)
{
pNodo n = new Nodo;
Uso de
punteros
if (n != NULL)
{
n->obj = o;
n->pSig = NULL;
}
else cout << "Error de memoria" << end;
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
return n;
Ejercicios
Listas
}
Notas
Operaciones básicas con listas (2/5)
Tema 6
Insertar un nodo al final:
A
Organización
de la memoria
C
G
L
Memoria estática
li
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
void insertarAlFinal(Lista &li, const Objeto &o)
{
if (esVacia(li))
li = crearNodo(o);
else
{
pNodo e = li;
Reserva y liberación
de memoria
while (e->pSig != NULL)
e = e->pSig;
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
e->pSig = crearNodo(o);
Parámetros de
funciones
}
Errores comunes
Ejercicios
Listas
}
P
Notas
Operaciones básicas con listas (3/5)
Tema 6
Insertar un nodo al principio:
Organización
de la memoria
A
Memoria estática
C
G
L
P
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
li
void insertarAlPrincipio(Lista &li, const Objeto &o)
{
if (esVacia(li))
li = crearNodo(o);
else
{
pNodo p = crearNodo(o);
p->pSig = li;
li = p;
}
}
Errores comunes
Ejercicios
Listas
Notas
Operaciones básicas con listas (4/5)
Tema 6
Mostrar el contenido de la lista:
Organización
de la memoria
A
Memoria estática
C
G
L
Memoria dinámica
Punteros
Definición y
declaración
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
Punteros y vectores
Punteros definidos
con typedef
li
void mostrar(Lista li)
{
pNodo e = li;
while (e != NULL)
{
cout << e->obj << endl; // Usar funcion si es necesario
e = e -> pSig;
}
}
Punteros y registros
Parámetros de
funciones
Errores comunes
Ejercicios
Listas
// Imprime: A C G L
Notas
Operaciones básicas con listas (5/5)
Tema 6
Organización
de la memoria
Memoria estática
Memoria dinámica
Punteros
Borrar una lista:
void borrarLista(Lista &li)
{
pNodo e = NULL;
Definición y
declaración
while (!esVacia(li))
{
e = li;
li = li -> pSig;
delete e;
}
Dirección y
contenido
Declaración con
inicialización
Ejercicios
Uso de
punteros
Reserva y liberación
de memoria
}
Punteros y vectores
Punteros definidos
con typedef
Punteros y registros
Parámetros de
funciones
Errores comunes
Las listas siempre deben borrarse cuando se hayan
terminado de usar
Ejercicios
Listas
Notas
Descargar