Pointer gestión avanzada de memoria dinámica de aplicaciones

El mejor momento para plantar un árbol es hace diez años, ¡seguido del ahora!

No digas tonterías, ¡vayamos al grano!

Al aprender matrices, solo podemos definir primero una matriz de longitud fija, pero ¿qué pasa con la situación real? Es posible que no hagamos esta matriz lo suficientemente larga debido a la demanda. (La longitud de la matriz antes de c99 solo puede ser una constante especificada de antemano). El lenguaje C señala la asignación de memoria dinámica. Utilizando la asignación de memoria dinámica, podemos diseñar una estructura de datos que se expanda o se contraiga según la demanda.

Una función de asignación de memoria dinámica

Aquí hay tres funciones de asignación de memoria. Son las tres funciones de malloc, calloc y realloc.

malloc: asigna el bloque de memoria, pero no inicializa el bloque de memoria

calloc: asigna un bloque de memoria y borra el bloque de memoria

reasignar-ajustar el tamaño del bloque de memoria asignado previamente

El prototipo de función de malloc: void * malloc (size_t size)

La más utilizada es la función malloc. Debido a que la función malloc no necesita borrar el bloque de memoria asignado, es más eficiente que la función calloc (accidentalmente escribí alta eficiencia en una palabra graciosa, jaja, muy gracioso, um, continuemos).

1.tipo de valor de retorno de Malloc:

Dado que no sabemos qué tipo de datos planeamos almacenar en el bloque de memoria, no devuelve int o punteros ordinarios de tipos como char, sino que devuelve punteros de tipo void * . El tipo vacío * se refiere a un puntero de "tipo universal".

Nota: No realice operaciones aritméticas en punteros de tipo void * , como aritmética de puntero, movimiento de puntero, etc., porque no sabemos qué tipo de puntero es + 1 no sé cuántos bytes se mueven.

2. Los parámetros de malloc:

La función malloc asigna un bloque de memoria de tamaño bytes y devuelve un puntero al bloque de memoria. Nota: El tipo de tamaño es un tipo entero sin signo, normalmente lo tratamos como un entero ordinario (a menos que se esté asignando un bloque de memoria muy grande (/ perro)).

3. Puntero nulo:

El espacio de memoria es limitado. Cuando se llama a la función de asignación de memoria, el espacio de memoria se agota y no se puede encontrar un bloque de memoria lo suficientemente grande. En este momento, la función devuelve un puntero nulo nulo. Un puntero nulo es un puntero que no apunta a ninguna parte.

Entonces, después de almacenar el valor de retorno de la función en la variable de puntero, necesitamos determinar si la variable de puntero es un puntero nulo. Si es así, tome las medidas apropiadas (generalmente printf se usa para solicitar información y exit (1) sale / regresa anormalmente a la llamada anterior, no hay mucho que decir aquí).

2. Libera espacio de almacenamiento

1. La memoria dinámica que solicitamos debe liberarse manualmente. Si malloc siempre se aplica para un bloque de memoria tras otro pero no lo libera, conducirá al agotamiento del montón (el bloque de memoria obtenido por malloc y otras funciones de asignación de memoria proviene de un grupo de almacenamiento llamado heap), lo que provocará la función para devolver el puntero vacío.

Incluso el programa puede asignar bloques de memoria y perder registros de estos bloques, desperdiciando así espacio, como:

q = malloc(...);
p = malloc(...);
p = q;

pyq respectivamente apuntan a diferentes bloques de memoria (llamamos bloque de memoria P y bloque de memoria Q), y p = q da la dirección de q ap, de modo que p también apunta al bloque de memoria Q, por lo que el bloque de memoria P se convierte en un bloque de memoria sin grabar, aunque se ha aplicado la aplicación pero se ha perdido el registro. De esta manera, el bloque de memoria inaccesible se llama basura, y el lenguaje C no tiene un mecanismo de recolección de basura, lo que significa que necesitamos recuperar manualmente esta memoria por nosotros mismos.

2. El método consiste en llamar a la función gratuita para liberar memoria innecesaria.

El prototipo de la función libre en <stdlib.h>:

void free (void * ptr);

Función: Libere el espacio de almacenamiento señalado por ptr. El espacio liberado generalmente se envía al grupo de almacenamiento disponible, que se puede redistribuir llamando a las funciones malloc, realloc y calloc más adelante.

Simplemente pase el puntero al bloque de memoria que ya no se necesita para la función libre:

int *p;
int n = 5;
p = malloc(sizeof(int) * n);
free(p);

free libera el bloque de memoria apuntado por p, y luego este bloque de memoria puede ser reutilizado por llamadas posteriores a la función malloc u otras funciones de asignación de memoria. Nota: ¡El parámetro libre debe ser el puntero devuelto por la función de asignación de memoria antes!

3. Puntero colgante

La función free (p) liberará el bloque de memoria apuntado por p, pero no cambiará p en sí mismo. Si olvida que p ya no apunta a un bloque de memoria válido, entonces ocurrirá un problema. En este caso, varios punteros apuntan al mismo bloque de memoria al mismo tiempo, y después de que se libera el bloque de memoria, todos los punteros quedan vacíos.

Intentar modificar o acceder al bloque de memoria liberado dará lugar a un comportamiento indefinido. Este es el riesgo potencial de punteros colgantes: acceder o modificar el bloque de memoria liberado sin nuestro conocimiento puede tener consecuencias graves.

Tres, matriz de asignación de memoria dinámica

Como se mencionó anteriormente, es difícil estimar el tamaño de la matriz cuando escribimos el programa, y ​​ahora podemos resolverlo: matriz de asignación de memoria dinámica. Asigne espacio para la matriz durante la ejecución del programa y luego acceda a la matriz a través de un puntero al primer elemento de la matriz.

Utilice la función malloc para asignar espacio de almacenamiento para la matriz

Suponiendo que el programa que se está escribiendo requiere una matriz de n enteros, n se calcula durante la ejecución de nuestro programa, necesitamos usar el operador sizeof para calcular el espacio requerido para cada elemento, y luego multiplicar por n como la función malloc Parámetros para asigne espacio de almacenamiento para esta matriz. (¡Utilice siempre la función sizeof cuando calcule la cantidad de espacio requerida para una matriz! Debido a las posibles diferencias del sistema, un entero de tipo int ocupa diferentes bytes y sizeof puede mejorar la portabilidad del código).

Una vez que a apunte a un bloque de memoria asignado dinámicamente, podemos ignorar el hecho de que a es un puntero y usarlo como el nombre de la matriz. Luego, ¡haga lo que quiera hacer con esta "matriz"!

 

 

Señale cualquier error, gracias ~~

 

Supongo que te gusta

Origin blog.csdn.net/qq_51182221/article/details/115145224
Recomendado
Clasificación