cpp-malloc-y-free

Qué es malloc y free en C++

En C++, malloc y free son dos funciones obsoletas utilizadas para la gestión de memoria dinámica (es decir, para reservar o liberar espacio en tiempo de ejecución).

Estas dos funciones son heredadas de C. Estas funciones están disponibles en C++ para mantener la compatibilidad con C.

Sin embargo, su uso en programas C++ modernos se desaconseja. En su lugar, en C++ la gestión de la memoria dinámica debe realizarse con new y delete.

No uséis malloc y free

Os lo cuento en este artículo porque que os la vais a encontrar en código de por ahí.

Pero en C++ se debería usar new y delete.

Qué es malloc

La función malloc (memory allocation) se utiliza para reservar un bloque de memoria dinámica de un tamaño específico.

Al usarlo, se reserva la memoria en el heap, y la dirección del bloque asignado se devuelve como un puntero void*.

#include <cstdlib> // Necesario para malloc

void* malloc(size_t size);
  • tamaño: Es la cantidad de memoria que se desea asignar (en bytes)
  • void*: Es un puntero genérico que se devuelve (debemos convertirlo al tipo de puntero deseado).

Si la asignación falla, devuelve nullptr.

Vamos a verlo el uso de malloc más claro con un ejemplo,

// Reserva memoria para un entero
int* p = (int*)malloc(sizeof(int)); 

if (p != nullptr) {
	*p = 10; // Inicializa el entero
	std::cout << *p << std::endl; // Imprime el valor
}

En este ejemplo,

  • Se asigna memoria para un entero.
  • Para obtener el tamaño en bytes de un tipo int usamos sizeof.
  • Tenemos que realizar un cast del puntero devuelto al tipo int*, ya que malloc devuelve un puntero de tipo void*.

Asignación de arrays dinámicos

malloc también puede utilizarse para asignar memoria para arrays dinámicos.

// Asigna memoria para un array de 5 enteros
int* arr = (int*) malloc(5 * sizeof(int)); 

La cantidad de memoria solicitada debe ser suficiente para almacenar todos los elementos del array.

Que es free

La función free se utiliza para liberar la memoria que fue previamente reservada con malloc (la memoria liberada puede ser reutilizada para futuras asignaciones)

void free(void* ptr);

Donde,

  • ptr: Un puntero a la memoria que se desea liberar.

Vamos a verlo con un ejemplo,

// Reservar memoria
int* p = (int*)malloc(sizeof(int)); 

if (p != nullptr) {
	free(p); // Libera la memoria
}

En este ejemplo,

  • Se asigna memoria para un entero
  • La liberamos inmediatamente (no muy útil, pero es un ejemplo).

Si no se libera la memoria después de su uso, se produce una fuga de memoria. Es decir, que tu programa va consumiendo más y más recursos por usarlos mal (y es una guarrada)

Desventajas y problemas

Ya hemos dicho que en C++ no deberíais usar malloc y free (salvo cuando tengáis código heredado de C, o necesitéis ser compatible con él) porque tiene importantes desventajas.

Vamos a ver algunas de ellas 👇

Gestión manual de memoria

El uso de malloc y free requiere que el programador gestione manualmente la memoria, lo que puede llevar a errores como:

  • Fugas de Memoria: No liberar memoria que ya no es necesaria.
  • Doble Liberación: Intentar liberar la misma memoria más de una vez.
  • Acceso a Memoria Liberada: Intentar acceder a la memoria después de haber sido liberada.

Falta de tipado seguro

Una de las principales desventajas de malloc y free es que trabajan con punteros void*, lo que significa que se requiere un casting explícito para convertir el puntero devuelto al tipo de dato correcto.

Falta de construcción y destrucción

malloc y free simplemente asignan y liberan memoria sin llamar a los constructores y destructores de los objetos.

Esto significa que no se realizan inicializaciones o limpiezas específicas del tipo de dato al usar estas funciones.