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

Antes de aprender la asignación de memoria dinámica de C, comprendamos:

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

Cuando especifica una variable usando un tipo de datos básico, el compilador C asigna automáticamente espacio de memoria a la variable en un grupo de memoria llamado apilado.

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


#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 de memoria contiguos, 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 se aprendió hasta ahora, cuando se determina un tipo básico de datos o matriz, la memoria se administra automáticamente. Sin embargo, existe un proceso para asignar memoria en C que le permitirá ejecutar un programa en el que el tamaño de la matriz es indeterminado hasta que ejecute su programa (tiempo de ejecución). Este proceso se llama «Asignación de memoria dinámica. »

En este tutorial, aprenderá:

Ahora puede crear y eliminar dinámicamente un conjunto de elementos 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 la pila.

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

FunciónPropósito
malloc ()Asigna el tamaño de memoria solicitado y devuelve el puntero al primer byte del espacio asignado.
calloc ()Asigna el espacio para los elementos de la matriz. Inicia los elementos a cero y vuelve a poner un puntero en la memoria.
realloc ()Se utiliza para modificar la cantidad de espacio de memoria asignado previamente.
Libre ()Libera o vacía el espacio de memoria asignado previamente.

Analicemos las funciones anteriores con su aplicación.

Sintaxis malloc () Función:

ptr = (cast_type *) malloc (byte_size);

Seo

Ejemplo de malloc ():

Example: ptr = (int *) malloc (50)

Tras la ejecución satisfactoria de esta declaración, se reserva un espacio de memoria de 50 bytes. La dirección del primer byte del espacio reservado se asigna al puntero 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));
    }
}

Producción:

Value of the 6th integer is 480
  1. Tenga en cuenta que tamaño (* ptr) usado en su lugar sizeof (int) para fortalecer el código cuando se escribe una declaración * ptr en un tipo diferente de datos más adelante.
  2. La asignación puede fallar si la memoria es insuficiente. En este caso, devuelve un puntero NULL. Por lo tanto, debe incluir un código para verificar el puntero NULL.
  3. Tenga en cuenta que la memoria asignada es contigua y se puede manejar como una matriz. Podemos usar aritmética de punteros para acceder a los elementos de la matriz en lugar de usar paréntesis [ ]. Recomendamos usar + para referirse a elementos de matriz porque increment ++ o + = cambia la dirección almacenada por el puntero.

La función Malloc () también se puede utilizar con el tipo de datos de caracteres, así como con tipos de datos complejos como estructuras.

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);
}

Producción

 Value of the 2nd integer is 50

Llamar a la función Syntax ():

ptr = (cast_type *) calloc (n, size);

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

Ejemplo de calloc ():

La siguiente tabla 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 (): Principales diferencias

La principal diferencia entre malloc () Vs calloc () C ª:

La función calloc () suele ser más apropiada y eficiente que la función malloc (). Si bien ambas funciones se utilizan para asignar espacio de memoria, calloc () puede asignar varios bloques a la vez. No tienes que pedir un bloqueo de memoria cada vez. La función calloc () se utiliza en estructuras de datos complejas que requieren más espacio de memoria.

El bloque de memoria asignado por calloc () en C siempre comienza a cero y en lugar de malloc () en C, siempre hay un valor de basura.

Sintaxis de la función realloc ():

ptr = realloc (ptr,newsize);

La declaración anterior asigna nuevo espacio de memoria con una cantidad especificada en el periódico variable. 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 si el bloque recién asignado se centra en el mismo lugar 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 estén seguros.

Ejemplo de realloc ():


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

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

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


#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]=%dn", i, arr_dynamic[i]);
        elements = 4;
        arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements
        printf("After reallocn");
        for (i = 2; i < elements; i++) arr_dynamic[i] = i;
        for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%dn", i, arr_dynamic[i]);
        free(arr_dynamic);
    } 

Resultado del programa de matriz dinámica en C en 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

Deja un comentario

Tu dirección de correo electrónico no será publicada.