5

Memoria dinámica

En este tutorial quiero añadir un poco de lo que sé acerca de los tipos de memoria que existen en el lenguaje C y cómo se distinguen entre sí.

<h1>Memoria estática</h1>

Cuando creamos un arreglo, de las dimensiones que sean, definimos en primera instancia el tamaño de cada una de sus dimensiones, es decir:

int bolas_billar[4];

El tamaño de ese arreglo es de 10 posiciones, es decir, irá desde el 0 hasta el 9, su tamaño es de 10, entonces puedo empezar a hacer algo como esto:

int bolas_billar[4];for(int i = 0; i < 4: i++)
	bolas_billar[i] = i;

Pero como pueden ver, me equivoqué, las bolas de billar no son 4, son 15, entonces tan sencillo como hacer:

int bolas_billar[4];for(int i = 0; i < 15: i++)
	bolas_billar[i] = i;

Pero estamos accediendo a memoria que no declaramos, pues nos estamos yendo hasta la posicion 14 y el arreglo es de 4, e incluso si hacemos:

int bolas_billar[4];for(int i = 0; i < 4: i++)
	bolas_billar[i] = i;int bolas_billar[15];

Es asignar memoria a la que no podemos acceder a menos que cambiemos directamente el arreglo desde la primera línea. Bueno pues se me ocurre una sencilla solución:

char nombre[100];

Como yo no sé cuál sea su nombre, voy a asignar 100 espacios para que no haya problemas. Pues sí, se abre un enorme problema y es:

<h3>Estás malgastando memoria</h3>

Porque quizás se ocupen menos de esos 100, ahora veamos otro caso.

<h1>Memoria pseudo-dinámica</h1>

Volviendo al problema inicial, nos queda suponer que otra solución sería que el usuario nos dé el tamaño del arreglo, soluciona nuestro problema porque no nos vamos a tener que romper la cabeza, ¿no?

printf("Bienvenido usuario, ingresa el tamaño de tu arreglo:\n");int size;
scanf("%i", &size);
char nombre[s];

¿Solucionado?, bueno pues deja te respondo con otra pregunta, ¿Crees que es óptimo que whatsapp (por ejemplo), te esté pidiendo que digites el tamaño del mensaje que vas a mandar ANTES DE ESCRIBIRLO?

A esto llamo yo memoria pseudo-dinámica porque parece que es cambiante pero sigue siendo la misma memoria estática

Entonces me gustaría introducirlos a MEMORIA DINÁMICA

<h1>#include <stdlib.h></h1>

standard library es la directiva que nos introduce las funciones:

  1. malloc()
  2. calloc()
  3. realloc()
  4. free()

malloc()
Empezamos con malloc(), malloc es la abreviación de memory allocation y lo que hace es que almacena un BLOQUE de memoria de cierto tamaño de bytes (dependiendo del tipo de dato) para lo que sea que lo vayas a utilizar, por ende, crea un arreglo donde se pueden almacenar un sólo tipo de valor. Devuelve un puntero que puede ser moldeado con cualquier tipo de dato.Su sintaxis es así:

ptr = (cast_type *) malloc(n_bytes_size);
//ejemplo más concreto
ptr = (int *)malloc(sizeof(int));

En este caso estamos reservando un bloque con 4 bytes que es el tamaño de un entero, si nuestro arreglo es unidimensional podemos omitir el (int i).Y si el bloque de memoria es insuficiente, devuelve un puntero en NULL.

calloc()
El nombre calloc es la abreviación de contiguos allocation (asignación contigua), la única diferencia entre malloc y calloc es que calloc reserva más de un sólo bloque de memoria y los inicializa con 0 a diferencia de malloc que si tu accedes a ese arreglo, te va a devolver basura, calloc te devuelve cero, a menos que necesites ese 0, es mejor usar malloc, porque es más rápido, sin embargo hay que asignarle algo porque de lo contrario sólo tendrá dentro basura.

La sintaxis de calloc es así:

ptr = (cast-type *)calloc(n, size_of_data_type);
//en términos más concretos
ptr = (float *)calloc(25, sizeof(float));

Éste va a reservar 25 bloques del tamaño del tipo de dato float

free()
Es una medida de seguridad para desalojar memoria que reservaste con malloc y/o calloc.

ptr = (float *)calloc(25, sizeof(float));
free(ptr); //Dentro está el apuntador que queremos vaciar

¿Cuándo usarlo? Bueno, me gusta responder con un ejemplo:
Imagina que entras a un salón sin niños y gritas ¡Fuera!, nadie va a salir porque no has metido niños, (no has asignado memoria), esto sería poner free antes que malloc/calloc:

free(ptr);
ptr = (float *)calloc(25, sizeof(float));

Si ahora metes niños y después gritas ¡FUERA!, ahora hay una posibilidad de que ellos salgan

ptr = (float *)calloc(25, sizeof(float));
free(ptr);

realloc()
Esta función lo que hace es que re-allocate (reasigna) memoria en un espacio el cuál ya estaba asignada, por ejemplo:

ptr = (float *)calloc(25, sizeof(float));
for(int i = 0; i < 25; i++)
	*ptr = i
ptr = realloc(ptr, n, sizeof(float));

Su sintaxis es:

realloc(variable_puntero, nuevo_bloque, el_tamaño_del_datatype);

El mismo tema del salón de clases, digamos que no se habían organizado los horarios, había muchos niños en la mañana, (malloc), en el transcurso de la tarde los cambiaron de turno (realloc), al otro día ya están mejor organizados. 😃

Ahora está resuelto el problema de las bolas de billar o el del nombre. Con estas funciones se pueden hacer muchas otras cosas más como arreglos dinámicos multidimensionales, si quieren que publique un código de esto, explicándolo línea por línea, sólo pídanlo. Espero les haya gustado, mucho éxito. Gracias por su atención.

Escribe tu comentario
+ 2
Ordenar por:
5
228Puntos

Great! This article gives the light in which we can observe the reality.

2
6Puntos

Interesting post! I hope you will continue to have similar posts to share with everyone. Krunker io