Función malloc() en la biblioteca C con EJEMPLO

⚡ Resumen inteligente

En C, la función malloc() reserva un bloque de memoria en el montón en tiempo de ejecución y devuelve un puntero void a su primer byte, lo que permite a los programas solicitar almacenamiento cuyo tamaño se desconoce hasta que el código se ejecuta realmente.

  • 🧠 Asignación en tiempo de ejecución: La función malloc() reserva memoria durante la ejecución cuando no se conoce el tamaño requerido en tiempo de compilación.
  • 📦 Sintaxis: Un puntero cast_type recibe malloc(byte_size), cuyo tamaño se suele determinar con sizeof para mayor portabilidad.
  • ⚠️ Comprobación de NULL: Una solicitud fallida devuelve un puntero NULL, por lo que debe validar el resultado antes de desreferenciarlo.
  • Aritmética de punteros: El bloque es contiguo, así que utilice + en lugar de ++ para acceder a los elementos del array.
  • 🧹 Libera la memoria: Libera cada bloque con free() para evitar fugas de memoria y punteros colgantes.
  • 🤖 Asistencia de IA: Los asistentes de IA y GitHub Copilot redactan llamadas a malloc() e indican que faltan declaraciones free().

Función malloc() en C

¿Qué es malloc en C?

La función malloc() significa asignación de memoria. Es una función que se utiliza para asignar un bloque de memoria de forma dinámica. Reserva espacio de memoria de un tamaño específico y devuelve el puntero nulo que apunta a la ubicación de la memoria. El puntero devuelto suele ser de tipo void. Significa que podemos asignar la función malloc a cualquier puntero.

¿Qué es malloc en C?

Sintaxis

ptr = (cast_type *) malloc (byte_size);

Aquí,

  • ptr es un puntero de cast_type.
  • La función malloc devuelve un puntero a la memoria asignada de byte_size.
Example: ptr = (int *) malloc (50)

Cuando esta declaración se ejecuta con éxito, se reserva un espacio de memoria de 50 bytes. La dirección del primer byte del espacio reservado se asigna al puntero ptr de tipo int.

Considere otro ejemplo de implementación de malloc:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

Salida:

Value of the 6th integer is 480

Observe que se utilizó sizeof(*ptr) en lugar de sizeof(int) para que el código sea más robusto cuando la declaración *ptr se convierta a un tipo de datos diferente más adelante.

La asignación puede fallar si la memoria no es suficiente. En este caso, devuelve un puntero NULL. Por lo tanto, debe incluir código para verificar si hay un puntero NULL.

Tenga en cuenta que la memoria asignada es contigua y puede tratarse como una matriz. Podemos usar puntero Se recomienda usar operaciones aritméticas para acceder a los elementos del array en lugar de corchetes [ ]. Aconsejamos usar + para referirnos a los elementos del array, ya que el incremento ++ o += modifica la dirección almacenada por el puntero.

La función malloc también se puede utilizar con el tipo de datos de carácter, así como con tipos de datos complejos como estructuras.

¿Por qué usar malloc() en C?

Los arreglos estáticos y las variables ordinarias fijan su tamaño cuando se compila el programa, lo que desperdicia espacio cuando el requisito resulta ser menor y falla por completo cuando resulta ser mayor. malloc() resuelve esto solicitando memoria en tiempo de ejecución, de modo que un programa puede dimensionar un búfer a la cantidad exacta de datos que recibe. Esta flexibilidad en tiempo de ejecución es el núcleo de asignación dinámica de memoria C ª.

La asignación dinámica con malloc() es la opción correcta en varias situaciones comunes:

  • La cantidad de datos de entrada se desconoce hasta que se ejecuta el programa, como por ejemplo la lectura de un archivo o una lista proporcionada por el usuario.
  • Se necesitan bloques grandes que desbordarían la pila limitada, ya que malloc() accede a la memoria desde el montón, que es mucho más grande.
  • Los datos deben sobrevivir a la función que los creó, ya que la memoria dinámica persiste hasta que se libera explícitamente.
  • Las estructuras y los arreglos deben aumentar o disminuir de tamaño mientras se ejecuta el programa.

Dado que el bloque reservado se devuelve como un puntero, se puede pasar entre funciones de forma económica sin copiar los datos subyacentes.

Cómo liberar la memoria asignada por malloc()

La memoria reservada por malloc() reside en el montón y nunca se libera automáticamente. Cuando un programa asigna memoria continuamente sin liberarla, consume gradualmente toda la memoria disponible, un problema conocido como fuga de memoria. La función free() devuelve un bloque de memoria terminado al sistema para que el espacio pueda reutilizarse.

La función free() toma un único argumento, el puntero que devolvió malloc(), y libera todo el bloque de memoria a la vez:

int *ptr;
ptr = malloc(10 * sizeof(int));
if (ptr != NULL) {
    /* use the allocated memory here */
    free(ptr);   /* release the block */
    ptr = NULL;  /* avoid a dangling pointer */
}

Siga estas reglas para gestionar la memoria dinámica de forma segura:

  • Llama a free() exactamente una vez por cada malloc() exitoso; liberar el mismo bloque dos veces provoca un comportamiento indefinido.
  • Tras liberar el puntero, este debe establecerse en NULL para que no pueda reutilizarse como un puntero colgante.
  • Nunca liberes con free() un puntero que malloc() no haya devuelto, incluyendo uno desplazado por aritmética de punteros.
  • Antes de que el puntero quede fuera del ámbito, haga coincidir cada asignación con una liberación correspondiente.

Keeping La asignación y liberación equilibrada de memoria es la disciplina fundamental de la gestión manual de memoria en C, y previene tanto las fugas de memoria como los fallos causados ​​por la reutilización de la memoria liberada.

malloc() vs calloc(): Diferencias clave

malloc() y calloc () Ambas funciones reservan memoria dinámica, pero difieren en sus argumentos y en cómo gestionan el nuevo bloque. `malloc()` toma un argumento, el número total de bytes, y deja el contenido sin inicializar, por lo que el bloque almacena valores basura impredecibles hasta que el programa escribe en él. `calloc()` toma dos argumentos, el número de elementos y el tamaño de cada uno, y borra cada byte antes de devolver el puntero.

Las diferencias prácticas se reducen a tres puntos:

  • Inicialización: calloc() inicializa la memoria a cero, mientras que malloc() no lo hace, lo que hace que malloc() sea ligeramente más rápido cuando los valores se van a sobrescribir de todos modos.
  • Argumentos: escribes malloc(n * size) pero calloc(n, size) para reservar el mismo array.
  • Caso de uso: elija calloc() cuando sea importante tener un bloque limpio y con valores cero, y malloc() cuando se prefiera la velocidad y la inicialización se realice manualmente.

Ambas funciones están declaradas en stdlib.h, ambas devuelven un puntero void o NULL en caso de fallo, y ambas liberan su memoria con la misma función free().

Preguntas Frecuentes

En C, la conversión es opcional y a menudo se desaconseja, porque void* se convierte automáticamente a cualquier puntero de objeto y una conversión explícita puede ocultar una inclusión faltante de stdlib.h. C++Sin embargo, se requiere el reparto.

Un valor NULL devuelto indica que la solicitud falló, generalmente por falta de memoria. Siempre verifique el puntero antes de usarlo, ya que desreferenciar NULL puede provocar un comportamiento indefinido y, por lo general, el programa se bloquea.

realloc() redimensiona un bloque previamente reservado por malloc(), keeping datos existentes hasta el tamaño más pequeño. Si falla, devuelve NULL y deja el bloque original intacto, así que asigne primero su resultado a un puntero temporal.

Se produce una fuga de memoria cuando la memoria asignada mediante malloc() nunca se libera con free(). El programa sigue reservando espacio que ya no utiliza, lo que puede agotar gradualmente la memoria disponible.

La función malloc() reserva memoria en el montón, no en la pila. Los bloques del montón permanecen válidos hasta que se llama a free(), por lo que pueden sobrevivir a la función que los creó, a diferencia de las variables automáticas de la pila que desaparecen al regresar.

malloc() es una función de biblioteca que devuelve void* y necesita sizeof para calcular los bytes. C++ `new` es un operador que devuelve un puntero tipado y llama a los constructores. Combina `malloc()` con `free()` y `new` con `delete`.

Sí. Los asistentes de codificación con IA redactan llamadas a malloc(), insertan comprobaciones de valores nulos, detectan llamadas a free() faltantes o fugas de memoria y pueden explicar la aritmética de punteros. Siempre compile y pruebe el código generado antes de confiar en él.

Copiloto de GitHub sugiere malloc(), sizeof() y las líneas correspondientes de free() de un comentario que describe su intención. RevRevisa cada sugerencia sobre comprobaciones de valores NULL faltantes y fugas de memoria antes de compilar.

Resumir este post con: