La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Tema 1. Estructuras de datos Objetivo: Objetivo: El alumno resolverá problemas de almacenamiento, recuperación y ordenamiento de datos y las técnicas de.

Presentaciones similares


Presentación del tema: "Tema 1. Estructuras de datos Objetivo: Objetivo: El alumno resolverá problemas de almacenamiento, recuperación y ordenamiento de datos y las técnicas de."— Transcripción de la presentación:

1 Tema 1. Estructuras de datos Objetivo: Objetivo: El alumno resolverá problemas de almacenamiento, recuperación y ordenamiento de datos y las técnicas de representación más eficientes, utilizando las estructuras para representarlos.

2 Contenido: 1.Representación de datos en memoria. 1. Tipos primitivos. 2. Arreglos. 3. Apuntadores 4. Tipo de dato abstracto. 2.Administración del almacenamiento en tiempo de ejecución. 3.Estructuras de datos compuestos. 1. Pila: almacenamiento contiguo y ligado, y operaciones. 2. Cola: almacenamiento contiguo y ligado, y operaciones. 3. Cola doble: almacenamiento contiguo y ligado, y operaciones. 4. Listas circular: almacenamiento contiguo y ligado, y operaciones. 5. Listas doblemente ligadas: almacenamiento contiguo y ligado, y operaciones. 1. Estructuras de Datos

3 Datos estáticos y datos dinámicos Datos estáticos: Su tamaño y forma es constante durante la ejecución de un programa y por tanto se determinan en tiempo de compilación. Por ejemplo los arreglos: tienen el problema de que hay que dimensionar la estructura de antemano, lo que puede conllevar desperdicio o falta de memoria. Datos dinámicos: Su tamaño y forma es variable (o puede serlo) a lo largo de un programa, por lo que se crean y destruyen en tiempo de ejecución. Esto permite dimensionar la estructura de datos de una forma precisa: se va asignando memoria en tiempo de ejecución según se va necesitando. 1.2 Memoria dinámica

4 Manejo de memoria en un programa o proceso 1.2 Memoria Dinámica

5 Memoria estática y memoria dinámica Memoria estática Es el espacio en memoria que se crea al declarar variables de cualquier tipo de dato (primitivas [int, char...] o derivados [struct, arreglos, apuntadores...]). La memoria que estas variables ocupan no puede cambiarse durante la ejecución y tampoco puede ser liberada manualmente. Memoria dinámica Es memoria que se reserva en tiempo de ejecución. Su principal ventaja frente a la estática, es que su tamaño puede variar durante la ejecución del programa. (En C, el programador es encargado de liberar esta memoria cuando no la utilice más). El uso de memoria dinámica es necesario cuando a priori no conocemos el número de datos/elementos a tratar. 1.2 Memoria Dinámica

6 Memoria estática y dinámica La memoria reservada de forma dinámica suele estar alojada en el heap o almacenamiento libre, y la memoria estática en el stack o pila. La pila generalmente es una zona muy limitada. El heap, en cambio, en principio podría estar limitado por la cantidad de memoria disponible durante la ejecución del programa y el máximo de memoria que el sistema operativo permita direccionar a un proceso. Sin embargo, se puede asumir es que muy probablemente dispondremos de menor espacio en la pila que en el heap. 1.2 Memoria Dinámica

7 Ventajas y desventajas Otra de las ventajas de la memoria dinámica, además de mayor espacio disponible, es que se puede ir incrementando durante la ejecución del programa. Esto permite, por ejemplo, trabajar con arreglos dinámicos. Una desventaja de la memoria dinámica es que es más difícil de manejar. La memoria estática tiene una duración fija, que se reserva y libera de forma automática. En contraste, la memoria dinámica se reserva de forma explícita y continúa existiendo hasta que sea liberada, generalmente por parte del programador. La memoria dinámica puede afectar el rendimiento. Puesto que con la memoria estática el tamaño de las variables se conoce en tiempo de compilación, esta información está incluida en el código objeto generado, por lo cual el proceso es muy eficiente. Cuando se reserva memoria de manera dinámica, se tienen que llevar a cabo varias tareas, como buscar un bloque de memoria libre y almacenar la posición y tamaño de la memoria asignada, de manera que pueda ser liberada más adelante. Todo esto representa una carga adicional, aunque esto depende de la implementación y hay técnicas para reducir su impacto. 1.2 Memoria Dinámica

8 Tiempo de vida Todos los datos tienen un tiempo de vida, es decir, el tiempo durante el cual se garantiza que el dato exista. En C, existen 3 tipos de duración: estática, automática y asignada. Las variables globales y las variables locales declaradas con el especificador static tienen duración estática. Se crean antes de que el programa inicie su ejecución y se destruyen cuando el programa termina. Las variables locales (no static) tienen duración automática. Se crean al entrar al bloque en el que fueron declaradas y se destruyen al salir de ese bloque. Duración asignada se refiere a los objetos cuya memoria se reserva de forma dinámica. Esta memoria se crea y se debe liberar de forma explícita. 1.2 Memoria Dinámica

9 Asignación dinámica de memoria Crear y mantener estructuras de datos dinámicas requiere de la asignación dinámica de memoria; es decir, la habilidad de un programa para obtener más espacio de memoria en tiempo de ejecución, para almacenar nuevos datos y para liberar espacio que ya no es necesario. La biblioteca estándar de C proporciona las funciones malloc, calloc, realloc y free para el manejo de memoria dinámica. Estas funciones están definidas en el archivo de cabecera stdlib.h. Las funciones malloc y free, así como el operador sizeof son básicos para la asignación dinámica de memoria. 1.2 Memoria Dinámica

10 La función MALLOC La función malloc toma como argumento el número de bytes que van a asignarse y devuelve un apuntador de tipo void* (apuntador a void) hacia la memoria asignada. void *malloc(size_t size) Un apuntador void* puede asignarse a una variable de cualquier tipo de apuntador. La función malloc normalmente se utiliza con el apuntador sizeof. Por ejemplo: apuntador = malloc(sizeof (struct cliente)); En este caso se evalúa sizeof(struct cliente) para determinar el tamaño en bytes de una estructura de tipo struct cliente, para asignar un área en memoria que coincida con ese número de bytes, y para almacenar un apuntador a la memoria asignada a la variable apuntador. La memoria asignada no se inicializa. Si no hay memoria disponible malloc devuelve NULL. 1.2 Memoria Dinámica

11 Ejemplos: int *i; … i = malloc(sizeof(int)); if (i == NULL) { /* Error al intentar reservar memoria */ } int *apuntador; char *apcarc; apuntador=(int *)malloc(4); puntcarc=(char *)malloc(200); 1.2 Memoria Dinámica int *arr1, n; printf("Numero de elementos del arreglo: "); scanf("%d", &n); arr1 = malloc(n * sizeof(int)); if (arr1 == NULL) { /* Error al intentar reservar memoria */ }

12 La función FREE La función free sirve para liberar memoria que se asignó dinámicamente. Si el apuntador es nulo, free no hace nada. void free(void *ptr) Ejemplo: int *i; i = malloc(sizeof(int)); … free(i); Una vez liberada la memoria, si se quiere volver a utilizar el apuntador, primero se debe reservar nueva memoria con malloc o calloc: 1.2 Memoria Dinámica

13 Buenas prácticas Siempre que se reserve memoria de forma dinámica con malloc, realloc o calloc, se debe verificar que no haya habido errores (verificando que el apuntador no sea NULL). Cuando se trata de verificar el valor de un apuntador (y sólo en ese caso), se puede usar de forma indistinta 0 (cero) o NULL. Usar uno u otro es cuestión de estilo. Las funciones de asignación dinámica de memoria devuelven un apuntador void. Las reglas de C establecen que un apuntador void se puede convertir automáticamente a un apuntador de cualquier otro tipo, por lo que no es necesario hacer una conversión (cast): int *i = (int *)malloc(sizeof(int)); Muchos programadores prefieren omitir la conversión anterior porque la consideran menos segura, ya que si accidentalmente se olvida incluir el archivo stdlib.h (donde están definidas malloc, calloc, realloc y free) en un programa que use dichas funciones, el comportamiento puede quedar indefinido. Si omitimos la conversión explícita, el compilador lanzará una advertencia. Si, en cambio, realizamos la conversión, el compilador generará el código objeto de forma normal, ocultado el bug. 1.2 Memoria Dinámica

14

15

16 La función CALLOC La función calloc funciona de modo similar a malloc, pero además de reservar memoria, inicializa a 0 (ceros) la memoria reservada. Se usa comúnmente para arreglos y matrices. void *calloc(size_t nmemb, size_t size); El parámetro nmemb indica el número de elementos a reservar, y size el tamaño de cada elemento. int *arr1, n; printf("Numero de elementos del arreglo: "); scanf("%d", &n); arr1 = calloc(n, sizeof(int)); if (arr1 == NULL) { /* Error al intentar reservar memoria */ } 1.2 Memoria Dinámica

17

18 La función REALLOC La función realloc redimensiona el espacio asignado de forma dinámica anteriormente a un apuntador. void *realloc(void *ptr, size_t size) Donde ptr es el apuntador a redimensionar, y size el nuevo tamaño, en bytes, que tendrá. Si el apuntador que se le pasa tiene el valor nulo, esta función actúa igual que malloc. Si la reasignación no se pudo hacer con éxito, devuelve un apuntador nulo, dejando intacto el puntero que se pasa por parámetro. Al usar realloc, se debería usar un apuntador temporal. De lo contrario, podríamos tener una fuga de memoria, si es que ocurriera un error en realloc. 1.2 Memoria Dinámica

19

20

21 Arreglos bidimensionales Un arreglo bidimensional es en realidad un arreglo cuyos elementos a su vez son arreglos también. Al ser el nombre de un arreglo unidimensional un apuntador, un arreglo bidimensional será un apuntador a apuntador. Para asignar memoria a un arreglo bidimensional (o multidimensional) se indica cada dimensión del arreglo de igual forma que uno unidimensional. Por ejemplo: int **arr2d = (int *)malloc( 10 * sizeof(int *) ); De esta manera se solicita la memoria para crear un arreglo de apuntadores que van a apuntar a cada fila del arreglo. En este caso el arreglo será de 10 apuntadores a enteros o 10 filas. arr2d[i] = (int*)malloc( elemFilas * sizeof( int ) ); Ahora se solicita memoria para almacenar el numero de elementos que va a formar cada fila o arreglo unidimensional dentro del arreglo de arreglos (bidimensional). 1.2 Memoria Dinámica

22

23

24

25


Descargar ppt "Tema 1. Estructuras de datos Objetivo: Objetivo: El alumno resolverá problemas de almacenamiento, recuperación y ordenamiento de datos y las técnicas de."

Presentaciones similares


Anuncios Google