Aprendiendo asignación dinámica de memoria: Función malloc
Bienvenidos una vez más
Saludos amigos de steemit, me contenta volver a estar con ustedes una vez más, les ofrezco disculpas por mi ausencia de casi 3 meses, esto se debe a que estaba ocupado con mis pasantías y no tenia tiempo para nada, en fin ya estoy de vuelta :) traigo conmigo un post bastante productivo en el campo de la programación, se trata de la "Asignación Dinámica De Memoria" estaré facilitando información para mayor comprensión de su gestión, funciones, funciones de asignación y la solución a un par de problemas que se nos puedan presentar, sin más que añadir a esta bienvenida demos inicio al post.
Introducción al tema
Podemos decir que los programas pueden crear ciertas variables globales o locales, cuando se trata de una declaración de variables globales, las posiciones son fijas en cuanto el almacenamiento de los programas, en la zona conocida como "Segmento de datos del programa" esto conlleva que todas las funciones pueden utilizar estas variables, por otro lado las variables locales se almacenan en la pila (stack) y existen sólo mientras están activas las funciones que están declaradas, se podría además, crear variables static, estas son: similares a las globales, pero se almacenan en posiciones fijas de memoria y sólo están disponibles en el módulo, en otras palabras en el archivo de texto.
Algunos conceptos claves que debemos tomar en cuenta
- Array Dinámico
- Array Estático
- Desbordamiento de memoria
- Función Free
- Función Malloc
- Gestión Dinámica
Gestión dinámica de la memoria
Vamos a tomar como ejemplo un programa que evalúe lo que vendrían siendo las calificaciones de los estudiantes de una asignatura. En el programa se almacena cada una de las calificaciones en los elementos de una lista o tabla y el tamaño del array tiene que ser lo suficientemente grande para contener el total de alumnos matriculados en la asignatura. Vamos a visualizar la siguiente sentencia:
int asignatura [40];
Reserva 40 enteros, que es un número fijo de elementos, para el caso de los arrays son un método bastante eficaz cuando se conoce lo que sería su longitud en el momento de escribir el programa, aunque presentan inconvenientes al momento de solo conocer el tamaño en la ejecución del programa, visualicemos ahora las siguientes sentencias que producirán un error al momento de la compilación:
scanf("%d",&num_estudiantes);
int asignatura[num_estudiantes];
Tomando como ejemplo que se desea almacenar una cadena de caracteres tecleada por el usuario, esta no se puede prever, a priori la longitud del array, a menos que se reserve un array de gran dimensión y se malgaste memoria cuando no se utilice, para efecto del ejemplo anterior debemos tomar en cuenta que si el número de alumnos de la clase aumenta, se debe variar la longitud del array y volver a compilar el programa.
Para resolver este problema lo ideal es utilizar el método que nos permita utilizar punteros y técnicas de asignación dinámica de memoria, el espacio de la variable que es asignada dinámicamente se crea durante la ejecución del programa, esto al contrario del caso de una variable local cuyo espacio se le asigna en tiempo de compilación.
Función Malloc()
Esta Función nos permite asignar un bloque de memoria que vendría siendo el número de bytes pasados como argumento, esta función devuelve un puntero que es la dirección del bloque asignado de memoria y este se utiliza para referenciar el bloque de memoria y devuelve un puntero del tipo void*, un ejemplo de esto sería de la siguiente forma:
puntero = malloc(tamaño en bytes);
Normalmente se hará una conversión al tipo del puntero:
tipo *puntero;
puntero =(tipo *) malloc(tamaño en bytes);
Tomamos como ejemplo:
long* p;
p = ("long") malloc(32);
El operador unario sizeof se utiliza a menudo en las funciones de asignación de memoria, el operador en este caso aplica a un tipo de dato el valor resultante que es el número de bytes que ocupa, entonces si por ejemplo se quiere reservar memoria para un buffer de 10 enteros:
int *r;
r = (int*) malloc(10*sizeof(int));
Cuando llamamos a la función malloc() puede ocurrir que no haya memoria disponible, siendo así la función malloc() devuelve NULL
Ejemplo práctico
Ahora que conocemos un poco más acerca de la función Malloc() vamos hacer una pequeña demostración, y crear un programa que reserve memoria para un nombre(string).
Código
Explicación
Declaramos las librerías correspondientes para poder utilizar la función Malloc, si necesitamos reservar memoria para un nombre debemos declarar una variable de tipo char, en la memoria estática pueden haber casos en que se desperdicie espacio, con la función Malloc esto no ocurrirá al momento en que queramos almacenar un determinado nombre.
Código
Explicación
Utilizamos la libreria string.h para hacer uso de la función strcpy y digitamos que la variable almacene la cadena de caracteres como mi nombre de usuario en steemit, en longitud tendremos el tamaño que tendrá mi nombre de usuario y la manera de calcularlo será haciendo uso de la función strlen para calcular la memoria exacta.
Código
Explicación
Por último imprimimos la longitud y al compilar podremos notar que la función strlen esta contando lo que vendrían siendo los datos exactos de la cadena más no esta contando el final de la cadena, un dato fundamental al tener en cuenta, greylml contiene 7 caracteres por lo que el programa esta funcionando correctamente.
Código
Explicación
Proseguimos utilizando la función malloc haciendo uso de longitud+1 (ya que este es el final de la cadena) y eso lo vamos a multiplicar por el sizeof el tamaño que va a tener el char, exactamente el tamaño de la cadena de caracteres, lo siguiente seria copiar mi nombre de usuario a la variable puntero, y se lo asignamos, al compilarlo podremos darnos cuenta que nos arroja como resultado mi nombre, fíjate que con p_nombre estoy utilizando los espacios necesarios que conforman mi nombre de usuario y así estoy ahorrando espacio en la memoria dinámica.
Fuente y despedida
Esto ha sido todo por el día de hoy, gracias por leer este post, espero que les haya servido de algo, comprender la función malloc y aplicarlo en algún ejercicio, pronto estaré subiendo más guías, nos vemos en una próxima oportunidad.
- Libro: Programación en C: Metodología, algoritmos, y estructura de datos
- Autor: Luis Joyanes Aguilar