Home
Username:
Password:
C Programming (Español) Tutorials

Memoria Dinámica / Soluciones del Capítulo 15




Visitors to VTC.com will be able to view all introductory videos for each training course.
Free Trial Members will gain access to first three chapters for each training course.
Full Access Members have full access to VTC.com’s entire library of video tutorials.


Learn More

Subtitles of the Movie

Estas son las soluciones a los ejercicios del capitulo 15 de la memoria dinamica. Este es el archivo "floats.c" para el problema de los tres tipos de memoriaÉ al tener un arreglo de 150 valores "float" de 3 maneras diferentes. Veamos cada una de ellas. Esta directiva "#define" se refiere al numero de elementos, asi que ingresamos el valor 150. Primero tenemos la version de la memoria estatica. Existen algunas maneras diferentes de crear una memoria en un area estatica. Primero, simplemente creamos una variable globalÉ que obviamente sera asequible desde este y cualquier archivo ".c" de este programa. Aqui tenemos solo una, pero si tuvieramos mas, estas tambien serian asequibles. Esa memoria se encuentra en un area estatica. Tambien podriamos simplemente anteponer la palabra reservada "static"É y tambien estaria en un area estatica. La unica diferencia seria que el ambito es distintoÉ porque aqui no podriamos acceder a esa variable en particular. La tercera manera de crear una memoria en un area estatica es ubicarla aqui; aun estaria en un area estatica de la memoria, pero ahora tiene un ambito completamente diferente, el cual esta restringidoÉ unicamente a la funcion "main". Aqui estamos realizando estas tres acciones en un solo proceso. El segundo arreglo de la memoria del "stack" es el mas sencillo de todos. Simplemente declaramos una variable dentro de la funcion "main" para ubicarla en el "stack". En cuanto a la memoria acumulada o la version dinamica, simplemente he creado un apuntador a un valor "float"É correspondiente a la direccion de memoria de un "float". Esto no crea 150 valores "float". De hecho, no crea ningunoÉ sino que simplemente crea la direccion de un "float". Por supuesto, solo debemos utilizar la funcion "malloc" aqui para crearlos. Aqui utilizamos la funcion "malloc" y aqui determinamos el tamano de la memoria requerida. Obviamente, necesitamos 150 elementos y cada uno de ellos tendra el tamano de un valor "float". No es necesario conocer cuantos bits contiene un "float"É sino que utilizamos el operador "sizeof". Luego debemos verificar si la funcion "malloc" ha asignado correctamente la memoria, lo cual recomiendo altamente. Tal vez usted no lo hizo en este ejercicio, pero debe adoptar este habito. Si la funcion "malloc" ha fallado, salimos del programa. De lo contrario, liberamos la memoria. Probablemente no es necesario hacer esto en este sencillo ejercicio, pero es conveniente adoptar este habito. Estos son los tres arreglos diferentes de 150 valores "float" creado de tres maneras distintas. Continuamos con el archivo "average.c" para el segundo ejercicio. Este es un programa muy sencillo. Aqui he creado una variable que sera el arreglo de los numeros enteros, ubicado en la memoria almacenada mediante la funcion "malloc" u otra similar. Una vez asignada la memoria, esta variable apuntadorÉ sera utilizada para apuntar a dicho arreglo que sera tratado como tal. Por supuesto, la primera pregunta es el tamano del arreglo: Àcuantos numeros queremos promediar? Una vez definimos la cantidad, podemos utilizarla como parte del calculo del tamano de la memoria. Obviamente multiplicamos a "count" por "sizeof(int)". De nuevo veremos verificar si la funcion "malloc" ha fallado o no. Luego salimos del programa porque no haremos nada mas. Ejecutamos el procedimiento estandar de la lectura de los numeros mediante la funcion "scanf" y sumamos un "int" al total. Esto es muy sencillo, pero esta es la parte dificil: Debemos tomar la direccion del elemento ubicado en la posicion "i" del arreglo cada vez. Recuerde que con la funcion "scanf" siempre debemos proveer la direccion del elemento al cual ingresamos los datosÉ y en este caso corresponde a uno de los elementos del arreglo "ptr". De hecho, debemos proveer la direccion del elemento de la posicion "i" del arreglo. Probablemente esta es la parte mas dificil de todo el programa. Una vez leemos lo valores, por supuestoÉ al acumularlos en el total, el resto es muy sencillo. De nuevo liberamos la memoria al final y desplegamos el promedio. Este es todo el programa. Ahora veamos la solucion del proyecto del curso. Aqui lo tenemos. Primero veamos las modificaciones realizadas en el archivo de encabezado. En primer lugar, el mayor cambio en este archivo corresponde al titulo y al artista. Estos ya no son arreglos de caracteres sino apuntadores a caracteres. Cada vez que creamos un nuevo CD tendremos una asignacion de espacio para el titulo y el artista. Obviamente, una vez asignado ese espacioÉ asignaremos este apuntador en particular a cada una de las areas de la memoria que hemos creado. Este es el unico cambio del archivo "database.h". Contrariamente, he realizado cambios sustanciales en el archivo "main.c". Veamoslos. Incluimos el archivo "stdlib.h" porque estamos asignando una memoria en este archivo "main.c". Este es el primer cambioÉ y es probablemente el mas importante de todos: este elemento "cds" ya no es un arreglo. sino un apuntadorÉ a una estructura "cd_t". Es decir, es la direccion de dicha estructura. Observe que ya no tenemos un arreglo para los detallesÉ porque ahora no tenemos una limitacion para el numero de CDs soportados por el programa. No he mencionado esto, pero en el archivo "database.h" tambien he eliminado las directivas "#define"É porque estas no son necesarias para indicar cuantos CDs puede manejar el programa, pues ya no tenemos un limite. Solo estamos limitados por la cantidad de memoria disponible, es decir, podemos continuar hasta que la funcion "malloc" nos indique que esta se ha agotado. Tampoco tenemos un limite para el tamano del titulo o el artista. Estos contenian 60 caracteres cada uno, pero ahora son basicamente ilimitados. Aqui teniamos un mensajeÉ que indicaba el maximo numero de CDs que la base de datos podia contener. Ya no lo tenemos porque no hay un valor maximo, asi que lo primero que hacemos es preguntar al usuario cuantos CDs desea ingresar. Esto determinara la cantidad maxima que el programa puede soportar. No utilizamos la funcion "read_int" anteriorÉ que se ejecutaba cada vez que queriamos leer un entero, sino que ahora la utilizamos como un valor entero para ahorrar un poco de programacion. Ese numero obtenido sera almacenado en la variable "count", asi que podemos utilizar dicha variable para decidir cuantos bytes de informacion seran reservados para el arreglo "cds". De nuevo debemos verificar si ese espacio es suficiente, pues el usuario podria haber ingresado un numero como 100 billonesÉ y claramente no vamos a ejecutar la funcion "malloc" 100 billones de veces por el tamano de un CD. La lectura de un CD ahora es un proceso muy sencillo. Aqui teniamos un ciclo "forever", pero ahora este es un sencillo ciclo "for". En la parte inferior no es necesario preguntarÉ si deseamos ingresar mas CDs porque el programa conoce exactamente dicha cantidad. Por supuesto, el despliegue de los CDs no ha cambiado mucho. Observe que la lectura de los CDsÉ y el despliegue de los mismos corresponden casi el mismo codigo, lo cual hace al programa mas consistente. Finalmente, en la parte inferior he incluido una liberacion de la memoria del titulo y el artista. No hemos visto el codigo en donde asignamos dicha memoria para el titulo y el artistaÉ porque lo veremos mas adelante, pero podemos asumir que esta asignada en algun punto. Si tenemos un CD, debemos liberar la memoria del titulo y el artista. Una vez ejecutamos este ciclo y liberamos dicha memoria, podemos liberar la memoria del arreglo "cds" en si. No debemos tomar esta linea de codigo y ubicarla antes del ciclo "for". No debemos liberar primero la memoria del arreglo "cds"É porque estaremos liberando una parte de la memoriaÉ e inmediatamente despuesÉ estaremos intentando acceder de nuevo a la misma memoriaÉ para manipular su contenido, asi que la liberacion de la memoria del arreglo "cds" debe ser la ultima accion. He realizado otros cambios en la funcion de lectura de datosÉ que se encuentra en el archivo "input.c". Veamos las modificaciones realizadas. Primero, he agregado esta desagradable linea para anular la definicion de una directiva del compilador denominada "strict ANSI". Esto es necesario porque el compilador Dev C++ que estoy utilizando tiene problemas con ese archivo en particular. Este es un "bug" del Dev C++ y no tiene nada que ver con este codigo. Si usted utiliza el Dev C++ debera incluir esta linea; de lo contrario, esta es completamente innecesaria. La he incluido porque vamos a manipular algunas cadenas en este archivo. Tambien tenemos esta directiva "#define" que veremos en un momento. Todas las modificaciones se encuentran en la parte inferior. En esta funcion "read_cd". teniamos un codigo completamente diferente. Esta funcion era utilizada para leer una cadena ubicada aqui y desplegarla ante el usuario. Aqui teniamos un apuntador para el titulo y luego el operador "sizeof" para determinar su tamano, pero ahora lo haremos de una manera ligeramente diferente. He escrito otra funcion en vez de "read_string"É llamada "read_dyn_string" para leer una cadena dinamica. Es decir, vamos a leer una cadena en la memoria utilizando la memoria dinamicaÉ y la utilizaremos para leer el titulo y el artista. La funcion "read_dyn_string" es diferente a la funcion "read_string" porque tiene como valor de restitucionÉ la cadena que representa el titulo, el artista, etc. Ya que el campo "title" es simplemente un apuntador, podemos hacer que este apunte a la parte de la memoria restituida por la funcion "read_dyn_string". Solo debemos asegurarnos de que la funcion "read_dyn_string"É restituya un apuntador a una parte de la memoria asignada dinamicamente. Veamos este aspecto. En la parte superior tenemos un comentario que explica este proceso indicandoÉ que la cadena en cuestion es asignada dinamicamente. Es muy importante incluir este comentarioÉ porque si este codigo es leido por otra personaÉ que no sabe como utilizar esta funcion en particular, debemos indicarle que el valor restituido por esta funcionÉ es una parte de la memoria dinamica que debe ser liberada. Si no lo hacemos, esa persona podria olvidar liberarla y comenzariamos a perder memoria. He decidido implementar esta funcion en particular al crear aqui una cadenaÉ ubicada en el "stack". Esta no es dinamicaÉ sino que es un bufer en el cual leemos los datos ingresados por el usuario desde el teclado. ÀQue tamano tendra ese bufer? Este debe ser tan extenso como puede serlo cualquier respuesta, asi que lo haremos mas grande que cualquier titulo, artista, etcÉ que pueda ser leido desde el teclado. Para esto tenemos la directiva "#define MAX 200" en la parte superior del programaÉ para indicar que el numero maximo sera 200. Declaramos dicha cadena en el "stack" y le asignamos directamenteÉ la respuesta ingresada por el usuario. Luego eliminamos las nuevas lineas de la cadena y esta es la parte ingeniosaÉ de la memoria dinamica: llamamos a la funcion "strdup". Si usted no la conoce, esta crea un duplicado exacto de la cadena que le pasamos, pero lo hace de manera dinamica asignando una parte de la memoria. Dentro de la funcion "strdup" se hace un llamado a la funcion "malloc". para asegurarnos de que la cadena restituida sea asignada dinamicamente. Simplemente pasamos esta cadena al lugar donde se ha llamado a esta funcionÉ y esta es la ultima accion requerida para que el programa funcione correctamente. Compilamos sin errores, ejecutamosÉ y se nos pregunta cuantos CDs queremos ingresar. ÀQue ocurre si ingresamos el valor 0? Salimos del programa. Intentemos de nuevo. Ingresamos el numero minimo de 1 CD. Escribimos algunos datos inventados, tendremos 3 pistas, este sera un album y el precio sera de 5 dolares. Esto es todo. El programa funciona muy bien. Con esto concluimos el capitulo de la memoria dinamica. ÀComo le fue con las soluciones?

Tutorial Information

Course: C Programming (Español)
Author: Mark Virtue
SKU: 33759
ISBN: 1-933736-81-X
Release Date: 2007-04-16
Duration: 21.5 hrs / 139 lessons
Captions: Available on CD and Online University
Compatibility: Vista/XP/2000, OS X, Linux
QuickTime 7, Flash 8

VTC Sign up & Benefits

  • Unlimited Access
  • 98,729 Video Tutorials (23,265 free)
  • Video Available as Flash or QuickTime
  • Over 1026 Courses
  • $30 for One Month Access
  • Multi-User Discounts Available