Asignación de memoria dinámica en C usando funciones malloc(), calloc()

Antes de aprender a asignar memoria dinámica C, comprendamos:

¿Cómo funciona la gestión de memoria en C?

Cuando declara una variable usando un tipo de datos básico, el compilador de C asigna automáticamente espacio de memoria para la variable en un grupo de memoria llamado montón.

Por ejemplo, una variable flotante suele ocupar 4 bytes (según la plataforma) cuando se declara. Podemos verificar esta información utilizando el tamaño de operador como se muestra en el siguiente ejemplo

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

La salida será:

 The size of float is 4 bytes

Además, una matriz con un tamaño específico se asigna en bloques contiguos de memoria, cada bloque tiene el tamaño de un elemento:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}

El resultado es:

 The size of the float array with 10 element is 40

Como hemos aprendido hasta ahora, al declarar un tipo de datos básico o una matriz, la memoria se gestiona automáticamente. Sin embargo, existe un proceso para asignar memoria en C que le permitirá implementar un programa en el que el tamaño de la matriz está indeciso hasta que ejecute su programa (tiempo de ejecución). Este proceso se llama “Asignación de memoria dinámica."

Asignación de memoria dinámica en C

Asignación de memoria dinámica Es la asignación y liberación manual de memoria según sus necesidades de programación. La memoria dinámica se administra y sirve con punteros que apuntan al espacio de memoria recién asignado en un área que llamamos montón.

Ahora puedes crear y destruir una serie de elementos dinámicamente en tiempo de ejecución sin ningún problema. En resumen, la administración automática de memoria usa la pila y la asignación de memoria dinámica C usa el montón.

La biblioteca tiene funciones responsables de la gestión dinámica de la memoria.

Función Finalidad
malloc () Asigna la memoria del tamaño solicitado y devuelve el puntero al primer byte de
espacio asignado.
calloc () Asigna el espacio para los elementos de una matriz. Inicializa los elementos a cero y devuelve un puntero a la memoria.
realloc () Se utiliza para modificar el tamaño del espacio de memoria previamente asignado.
Gratis() Libera o vacía el espacio de memoria previamente asignado.

Analicemos las funciones anteriores con su aplicación.

función malloc() en C

La función C 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 nulo. Significa que podemos asignar la función C malloc() a cualquier puntero.

Sintaxis de malloc() Función:

ptr = (cast_type *) malloc (byte_size);

Aquí,

  • ptr es un puntero de cast_type.
  • La función C malloc() devuelve un puntero a la memoria asignada de byte_size.

Ejemplo de malloc():

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:

#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

Función C malloc()

  1. Darse cuenta de tamaño de(*ptr) se usó en lugar de tamaño de (int) para hacer que el código sea más robusto cuando la declaración *ptr se convierta a un tipo de datos diferente más adelante.
  2. 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.
  3. Tenga en cuenta que la memoria asignada es contigua y se puede tratar como una matriz. Podemos utilizar la aritmética de punteros para acceder a los elementos de la matriz en lugar de utilizar corchetes [ ]. Recomendamos utilizar + para hacer referencia a los elementos de la matriz porque el uso de incrementos ++ o += cambia la dirección almacenada por los elementos de la matriz. 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.

función gratuita () en C

El recuerdo para las variables se desasigna automáticamente en el momento de la compilación. En la asignación de memoria dinámica, debe desasignar la memoria explícitamente. Si no lo hace, es posible que encuentre un error de falta de memoria.

El libre() Se llama a esta función para liberar/desasignar memoria en C. Al liberar memoria en su programa, deja más memoria disponible para su uso posterior.

Por ejemplo:

#include <stdio.h>
int main() {
int* ptr = malloc(10 * sizeof(*ptr));
if (ptr != NULL){
  *(ptr + 2) = 50;
  printf("Value of the 2nd integer is %d",*(ptr + 2));
}
free(ptr);
}

Salida:

 Value of the 2nd integer is 50

función calloc() en C

La función calloc() de C significa asignación contigua. Esta función se utiliza para asignar múltiples bloques de memoria. Es una función de asignación de memoria dinámica que se utiliza para asignar memoria a estructuras de datos complejas, como matrices y estructuras.

La función Malloc() se usa para asignar un solo bloque de espacio de memoria, mientras que calloc() en C se usa para asignar múltiples bloques de espacio de memoria. Cada bloque asignado por la función calloc() es del mismo tamaño.

Sintaxis de calloc() Función:

ptr = (cast_type *) calloc (n, size);
  • La declaración anterior se utiliza para asignar n bloques de memoria del mismo tamaño.
  • Una vez asignado el espacio de memoria, todos los bytes se inicializan a cero.
  • Se devuelve el puntero que se encuentra actualmente en el primer byte del espacio de memoria asignado.

Siempre que hay un error al asignar espacio de memoria, como por ejemplo falta de memoria, se devuelve un puntero nulo.

Ejemplo de calloc():

El siguiente programa calcula la suma de una secuencia aritmética.

#include <stdio.h>
    int main() {
        int i, * ptr, sum = 0;
        ptr = calloc(10, sizeof(int));
        if (ptr == NULL) {
            printf("Error! memory not allocated.");
            exit(0);
        }
        printf("Building and calculating the sequence sum of the first 10 terms \ n ");
        for (i = 0; i < 10; ++i) { * (ptr + i) = i;
            sum += * (ptr + i);
        }
        printf("Sum = %d", sum);
        free(ptr);
        return 0;
    }

Resultado:

Building and calculating the sequence sum of the first 10 terms
Sum = 45

calloc() vs malloc(): diferencias clave

A continuación se muestra la diferencia clave entre malloc() Vs calloc() C ª:

La función calloc() es generalmente más adecuada y eficiente que la función malloc(). Si bien ambas funciones se utilizan para asignar espacio de memoria, calloc() puede asignar múltiples bloques a la vez. No es necesario solicitar un bloque de memoria cada vez. La función calloc() se utiliza en estructuras de datos complejas que requieren mayor espacio de memoria.

El bloque de memoria asignado por calloc() en C siempre se inicializa a cero, mientras que en la función malloc() en C, siempre contiene un valor basura.

función realloc() en C

Usando la C realloc () función, puede agregar más tamaño de memoria a la memoria ya asignada. Expande el bloque actual dejando el contenido original como está. realloc() en C significa reasignación de memoria.

realloc() también se puede utilizar para reducir el tamaño de la memoria previamente asignada.

Sintaxis de la función realloc():

ptr = realloc (ptr,newsize);

La declaración anterior asigna un nuevo espacio de memoria con un tamaño específico en la variable newsize. Después de ejecutar la función, el puntero volverá al primer byte del bloque de memoria. El nuevo tamaño puede ser mayor o menor que la memoria anterior. No podemos estar seguros de que el bloque recién asignado apunte a la misma ubicación que el bloque de memoria anterior. Esta función copiará todos los datos anteriores en la nueva región. Se asegura de que los datos permanezcan seguros.

Ejemplo de reasignación():

#include <stdio.h>
int main () {
   char *ptr;
   ptr = (char *) malloc(10);
   strcpy(ptr, "Programming");
   printf(" %s,  Address = %u\n", ptr, ptr);

   ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
   strcat(ptr, " In 'C'");
   printf(" %s,  Address = %u\n", ptr, ptr);
   free(ptr);
   return 0;
}

Siempre que la función realloc() en C da como resultado una operación fallida, devuelve un puntero nulo y también se liberan los datos anteriores.

Matrices dinámicas en C

Una matriz dinámica en C permite que la cantidad de elementos crezca según sea necesario. Las matrices dinámicas de C se utilizan ampliamente en algoritmos de ciencias de la computación.

En el siguiente programa, hemos creado y redimensionado una matriz dinámica en C

#include <stdio.h>
    int main() {
        int * arr_dynamic = NULL;
        int elements = 2, i;
        arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
        for (i = 0; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        elements = 4;
        arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
        printf("After realloc\n");
        for (i = 2; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
        free(arr_dynamic);
    }

Resultado del programa C Dynamic Array en la pantalla:

 
arr_dynamic[0]=0
arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0
arr_dynamic[1]=1
arr_dynamic[2]=2
arr_dynamic[3]=3

Resumen

  • Podemos administrar la memoria dinámicamente creando bloques de memoria según sea necesario en el montón
  • En C Dynamic Memory Allocation, la memoria se asigna en tiempo de ejecución.
  • La asignación de memoria dinámica permite manipular cadenas y matrices cuyo tamaño es flexible y se puede cambiar en cualquier momento en su programa.
  • Es necesario cuando no se tiene idea de cuánta memoria ocupará una estructura en particular.
  • Malloc() en C es una función de asignación de memoria dinámica que significa asignación de memoria que bloquea la memoria con el tamaño específico inicializado a un valor basura
  • Calloc() en C es una función de asignación de memoria contigua que asigna múltiples bloques de memoria a la vez inicializados en 0
  • Realloc() en C se utiliza para reasignar memoria según el tamaño especificado.
  • La función Free() se utiliza para borrar la memoria asignada dinámicamente.