Para esta actividad se utilizará la siguiente tabla:
Aspecto | C | Java |
---|---|---|
Llamada para obtener memoria | ||
La reserva de memoria precisa tamaño | ||
Más de una función disponible para reserva/creación | ||
¿Se inicializa la memoria reservada? | ||
Llamada para destruir/liberar memoria | ||
Llamada para cambiar el tamaño de un bloque previamente reservado | ||
¿Es posible acceder fuera de los límites de un bloque reservado? | ||
¿Qué sucede cuando el puntero a un bloque de memoria reservado se pierde (no está almacenado ya en ninguna variable)? |
En grupos de cuatro personas y durante cinco minutos, completar el cuadro anterior consensuando las respuestas.
Las respuestas de cada grupo se ponen en común con el resto de la clase para rellenar una tabla común.
Resuelve los trece primeros problemas. Si tras resolverlos tienes dudas sobre el funcionamiento de la gestión de memoria acude a consultas con el profesor. Si ves que los conceptos los tienes claros, resuelve los problemas restantes.
Resuelve los cuatro problemas que se plantean en el segundo documento. Asegúrate de que asistes a la sesión magistral con ellos bien entendidos.
En la siguiente clase se utilizarán estos conceptos para resolver un problema de gestión de memoria, por lo que necesitarás las soluciones para responder correctamente a las preguntas.
Comprueba con estas preguntas si has entendido este documento
Indique los errores que encuentra en cada trozo de código.
1 2 3 4 5 6 7 8 9 10 11 12 | int count_element(int id, struct list *inicio) { int cont=0; struct list *aux= (struct list *) malloc (sizeof(struct list)); aux=inicio; while (aux!=NULL) { cont++; aux=aux->next; } return cont; } |
1 2 3 4 5 6 7 8 9 10 11 12 | int count_element(int id, struct list **inicio) { int cont=0; struct list *aux; aux=*inicio; while (*inicio!=NULL) { cont++; *inicio=(*inicio)->next; } return cont; } |
1 2 3 4 5 6 7 8 9 10 11 12 | int count_element(int id, struct list *inicio) { int cont; struct list *aux; aux=inicio; while (aux!=NULL) { cont++; aux=aux->next; } return cont; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | struct list *del_element(int id, struct list *inicio) { struct list *aux,*ant; aux=inicio; ant=inicio; while ((aux!=NULL)&&(aux->id!=id)) { ant=aux; aux=aux->next; } if (aux == NULL) return inicio; if (aux == ant) { free(aux); inicio=inicio->next; } else { ant->next=aux->next; free(aux); } return inicio; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | struct list *del_element(int id, struct list *inicio) { struct list *aux,*ant; aux=inicio; while ((aux!=NULL)&&(aux->id!=id)) { ant=aux; aux=aux->next; } if (aux == NULL) return inicio; if (aux == ant) { inicio=inicio->next; free(aux); } else { ant->next=aux->next; free(aux); } return inicio; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | struct list *del_element(int id, struct list *inicio) { struct list *aux,*ant; aux=inicio; ant=inicio; while ((aux!=NULL)&&(aux->id!=id)) { ant=aux; aux=aux->next; } if (aux == NULL) return inicio; if (aux == ant) { inicio=inicio->next; free(aux); } else { ant->next=aux->next; } return inicio; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | struct vector *create_vector(int number) { if (number == 0) return NULL; struct vector *nuevo= (struct vector *) malloc(sizeof(struct vector)*number); if (nuevo == NULL) return NULL; int i=0; while (i≤number) { nuevo[i]=i; i++; } return nuevo; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | struct vector *create_vector(int number) { if (number == 0) return NULL; struct vector *nuevo= (struct vector *) malloc(sizeof(struct vector)*number); if (nuevo == NULL) return NULL; int i; while (i<number) { nuevo[i]=i; i++; } return nuevo; } |
Un programa en C necesita manipular un conjunto de palabras. Se nos encarga la tarea de implementar esta funcionalidad y para ello se nos ofrece la siguiente descripción de requisitos:
La aplicación puede manipular varios conjuntos separados de palabras.
El orden y la forma en que se almacenan las palabras en la estructura de datos no es relevante para el resto de la aplicación.
Las operaciones que se deben soportar son:
Obtener un conjunto vacío.
Dada una palabra, obtener un conjunto con esa única palabra.
Dado un conjunto y una palabra, obtener el nuevo conjunto que contenga la palabra dada.
Dado un conjunto y una palabra, devolver un conjunto que no contenga la palabra dada. Si la palabra no existe, el conjunto no se modifica
Destruir un conjunto de palabras dado.
Todas las operaciones que reciben una palabra y la
almacenan, deben crear un duplicado con la llamada al sistema
strdup
. Esta función recibe una cadena de tipo char
*
terminada por un byte igual a cero y devuelve una cadena (de
tipo char *
) que es un duplicado del parámetro en una
porción de memoria reservada con malloc
.
La solución propuesta debe ser compacta, es decir, tener un uso de memoria lo más reducido posible.
En grupos de cuatro personas, discutir durante cinco minutos la estructura de datos que se propone para manipular estos conjuntos de cadenas de texto. Escribir su definición en C. Comentar la solución propuesta con el resto de la clase. Derivar una propuesta final sobre la que trabajarán todos los grupos.
El equipo propone una implementación de la función que devuelve un conjunto vacío y la que devuelve un conjunto con una única palabra. Comprobar la solución propuesta con el profesor.
El equipo propone una implementación para la función que inserta una palabra en un conjunto. Prestar especial atención al tipo de datos que debe devolver esta función.
Escribir las definiciones de las cabeceras de las dos funciones restantes (la que borra un elemento y la que destruye un conjunto).
Supongamos que ya tenemos escritas todas las funciones, ahora el resto de la aplicación las quiere usar, pero tal y como se incluye en la especificación, no se requiere saber cómo están almacenados los datos internamente. ¿Cómo organizarías el código y las definiciones para conseguir esto?
Implementar una de las dos funciones restantes.