Departamento de Informática Departamento de Informática Universidad Técnica Federico Santa María Lenguajes de Programación Universidad Técnica Federico Santa María Lenguajes de Programación Tipo Puntero • Su valor corresponde a una dirección de memoria, habiendo un valor especial nulo (nil) que no apunta a nada. • Aplicaciones: 2.5 Tipo Puntero – ŒMétodo de gestión dinámica de memoria (acceso a variables dinámicas de heap) – •Método de direccionamiemto indirecto Operaciones, problemas de uso, tipo referencia, implementación y gestión del heap • No corresponde a un tipo estructurado, aun cuando se definen en base a un operador de tipo. 1 RMA/2000 Departamento de Informática Universidad Técnica Federico Santa María RMA/2000 II- 2 Departamento de Informática Lenguajes de Programación Operaciones con Punteros Ejemplo en C • Asignación: asigna a la variable como valor una dirección a algún objeto de memoria. • Desreferenciación: entrega el valor del objeto apuntado. 7023 432 432 2145 ptr int j, *ptr; – Operador * en C y C++ (e.g. * ptr) 7127 – Operador ^ en Pascal (e.g. ptr^) II- 3 Departamento de Informática RMA/2000 II- 4 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Problema con Punteros Lenguajes de Programación Problema con Punteros • Œ Dejar colgado (dangling) • •Pérdida de variables dinámicas de heap typedef tipo* ptipo; tipo x; ptipo p, q; tipo* p= ( ptipo) malloc(sizeof(tipo)); ... q= p; ... free(p); ... /* puede que la variable de heap sea reasignada */ *q = x; RMA/2000 ptr= (int*) malloc(sizeof(int)); *ptr = 432; j = *ptr; j RMA/2000 Universidad Técnica Federico Santa María Lenguajes de Programación Universidad Técnica Federico Santa María II- 5 p; p= (tipo *) malloc(sizeof(tipo)); ... p= (ptipo *) malloc(sizeof(tipo)); /* se pierde la variable asignada anteriormente */ • Se pierde el acceso a la variable, convirtiéndose en basura dado que no puede ser reasignada RMA/2000 II- 6 Departamento de Informática Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Ejemplo de Punteros en Pascal Punteros y Estructuras en C y C++ struct nodo_t { tipodato info; struct nodo_t *siguiente; }; typedef nodo_t* enlace_t; TYPE enlace_t = ^nodo_t; nodo_t = RECORD info : tipo_dato; siguiente: enlace_t END; VAR lista, nodo: enlace_t; enlace_t nodo; #ifndef C++ nodo = ( enlace_t) malloc(sizeof(nodo_t)); #elif nodo = new nodo_t; /* caso C++ */ #endif (*nodo). info = dato; BEGIN ... new(nodo); nodo^.info := dato; nodo^.siguiente := lista; lista := nodo; /* forma más conveniente de referirse es */ nodo->siguiente = NULL; RMA/2000 II- 7 Departamento de Informática Punteros y Arreglos en C y C++ II- 8 #define ALLOCSIZE 1000 /* tamaño del buffer */ static char allocbuf[ALLOCSIZE]; /* el buffer */ static char* allocp = allocbuf; /* primera posición libre */ char *alloc( int n) / retorna puntero a “n” caracteres */ { i f (allocbuf + ALLOCSIZE – allocp >= n) { /*si cabe */ allocp += n; return allocp – n; /* antigua direccion */ } else return 0; } int a[10]; int *pa; pa = &a[0]; pa = a; /* hace lo mismo que la linea anterior */ for (int i=0; i<10; i++) for (int i=0; i<10; i++) for (int i=0; i<10; i++) /* los tres for hacen lo Lenguajes de Programación Universidad Técnica Federico Santa María Aritmética de Punteros en C y C++ • Un arreglo es en realidad una constante de tipo puntero printf(a[i]); printf(*( pa+i)); printf(*( a+i)); mismo */ void afree ( char *p) { i f (p >= allocp && p < allocp + ALLOCSIZE) allocp = p; } RMA/2000 II- 9 Departamento de Informática RMA/2000 II- 10 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Tipo Referencia en C++ Universidad Técnica Federico Santa María Lenguajes de Programación Referencias en Funciones de C++ • Un tipo referencia es una variable tipo puntero constante que es implícitamente desreferenciada . • Dado que es constante, debe ser inicializada en su definición. int valor = 3; int &ref_valor = valor; /* ahora valor == 100 */ • La referencia actúa como alias de una variable. RMA/2000 RMA/2000 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María ref_valor = 100; Lenguajes de Programación Universidad Técnica Federico Santa María II- 11 • Su uso en parámetros de funciones permite pasada por referencia (comunicación bidireccional). • Inicialización se produce en el momento de la invocación. void swap( int &a, int &b) { int tmp = a; a = b; b = tmp; } ... int a, b; ... swap(a,b); ... RMA/2000 void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } ... int a, b; ... swap(&a,&b); ... II- 12 Departamento de Informática Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Lenguajes de Programación Universidad Técnica Federico Santa María Referencias en Java Técnicas para evitar Dangling • Java extiende la forma de variables de referencia de C++, haciendo innecesario y, por lo tanto, eliminando el uso de punteros. • Lápida sepulcral (tombstone) • Enfoque de Llave y Claves (locks-and-keys) • No existe liberación explícita (e.g. Java) – Java permite asignar un nuevo objeto a una variable de referencia – Todo objeto sólo se referencia con estas variables • En Java liberación de objetos es implícita RMA/2000 II- 13 Departamento de Informática RMA/2000 II- 14 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Lenguajes de Programación Universidad Técnica Federico Santa María Œ Método de la Lápida Sepulcral • Método de Llave y Clave (Tombstone) (Locks-and-Keys) key1 address Heap Tombstones Heap Variables Dinámicas key2 address lock data key1 = lock key2 ≠ lock RMA/2000 II- 15 Departamento de Informática Universidad Técnica Federico Santa María II- 16 Departamento de Informática Lenguajes de Programación Gestión del Heap Universidad Técnica Federico Santa María Lenguajes de Programación Casos para una Celda de Heap • Situación más simple es administrar objetos de memoria (o celda) de un tamaño único • Libre: no tiene referencias y está marcada libre • Ocupada : tiene al menos una referencia y está asignada (no está marcada como libre) – Celdas libres se pueden enlazar con punteros en una lista – Asignación es simplemente tomar suficientes celdas (contiguas) de la lista anterior – Liberación es un proceso más complicado (se debiera evitar dangling y basura). • Basura: No tiene referencia y no está marcada como libre ∴ el administrador no la puede reasignar • Tamaño variable es lo normalmente requerido por los lenguajes, pero es complejo de implementar RMA/2000 RMA/2000 II- 17 • Dangling : tiene alguna referencia y está marcada como libre ∴ el administrador la podría reasignar RMA/2000 II- 18 Departamento de Informática Universidad Técnica Federico Santa María Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Métodos de Reclamo de Basura Recolección de Basura • Contadores de Referencia (impaciente) void* allocate (int n) { if (!hay_espacio) { /* recolectar basura */ 1) marcar todo los objetos del heap como basura; 2) for (todo puntero p) { if (p alcanza objeto o en el heap) marcar o como NO basura; } /* for */ 3) liberar todos los objetos marcados como basura } – Se mantiene un contador de referencia por cada celda – Se incrementa con una nueva referencia y se decrementa cuando se pierde una referencia – Celda se libera tan pronto cuenta llega a cero (cuando se convierte en basura) • Recolección de Basura (perezoso) if (hay_espacio) { asignar espacio; return puntero al objeto; } else return NULL; – Se acumula basura hasta que se agota la memoria – Si se agota la memoria se identifican las celdas de basura y se pasan a la lista de celdas libres RMA/2000 } II- 19 Departamento de Informática Universidad Técnica Federico Santa María RMA/2000 II- 20 Departamento de Informática Lenguajes de Programación Universidad Técnica Federico Santa María Evaluación de los Métodos Lenguajes de Programación Celdas de Tamaño Variable • Contadores de referencia – Requiere bastante memoria para mantener contadores – Asignaciones a punteros requiere de más tiempo de ejecución para mantener contadores • Recolección de basura – Basta un bit por celda para marcar basura – Mal desempeño cuando queda poca memoria RMA/2000 Lenguajes de Programación II- 21 • Mayor parte de los lenguajes requieren variables de tamaño variable. • Mantención de celdas asignadas y libres se hace más difícil y costosa. • Se requiere más memoria para mantener información sobre tamaño, estado, etc. • Se produce fragmentación de la memoria. RMA/2000 II- 22