Asignación dinámica de memoria en C: malloc(), calloc()
⚡ Resumen inteligente
La asignación dinámica de memoria en C reserva y libera memoria del montón en tiempo de ejecución utilizando las funciones malloc(), calloc(), realloc() y free() de la biblioteca stdlib.h, lo que permite a los programas dimensionar matrices y estructuras de forma flexible cuando se desconocen los requisitos antes de la ejecución.
¿Cómo funciona la gestión de memoria en C?
Cuando se declara una variable utilizando un tipo de dato básico, el compilador de C asigna automáticamente espacio de memoria para la variable en un grupo de memoria llamado pila.
Por ejemplo, una variable de tipo float suele ocupar 4 bytes (según la plataforma) al declararse. Podemos verificar esta información utilizando el operador sizeof, 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 ya hemos visto, al declarar un tipo de dato básico o un array, la memoria se gestiona automáticamente. Sin embargo, en C existe un proceso para asignar memoria que permite implementar un programa cuyo tamaño no se define hasta la ejecución (tiempo de ejecución). Este proceso se denomina "asignación dinámica de memoria".
Asignación de memoria dinámica en C
La asignación dinámica de memoria (DMA) consiste en la asignación y liberación manual de memoria según las necesidades de programación. La memoria dinámica se gestiona y se sirve mediante punteros que apuntan al espacio de memoria recién asignado en un área que denominamos montón (heap).
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 | Propósito |
|---|---|
| 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
- 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 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.
La función free() se utiliza para liberar memoria en C. Al liberar memoria en tu programa, dejas 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
Mediante la función realloc() de C, puedes añadir más memoria a una memoria ya asignada. Esta función expande el bloque actual sin modificar el contenido original. En C, realloc() 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


