Notas de gestión de memoria dinámica

¿Por qué existe una gestión de memoria dinámica?

  1. Bajo diferentes requisitos, es posible que el espacio deba ajustarse continuamente, lo que da como resultado una disminución en la escalabilidad del código.
  2. Puede ser que la división del espacio no sea razonable, lo que puede conducir a una pérdida de espacio.
  3. Generalmente, en la pila, el espacio que se puede asignar de manera efectiva al mismo tiempo es limitado.

Por las razones anteriores, se requiere la administración de memoria dinámica. Los beneficios de la administración de memoria dinámica son:

  1. Decidamos el tamaño del espacio abierto durante la ejecución del programa. Dé tanto como aplique.
  2. Usa el espacio de manera eficiente. No causará una pérdida de espacio.
  3. Hay más espacio disponible. Espacio de pila> espacio de pila.

La gestión dinámica de la memoria consiste en solicitar espacio en el área del montón, y el espacio aplicado es continuo.
En la pila, la pila: aplicación automática, liberación automática. Los usuarios no necesitan realizar una gestión de memoria dinámica.
Espacio dinámico: debe solicitar espacio usted mismo y liberarlo usted mismo: gratis.

 
 
 
función malloc

原型 : void * malloc (tamaño_t tamaño);

La función malloc se aplica a un espacio disponible continuo de la memoria y devuelve un puntero a este espacio.

  • Si el desarrollo es exitoso, regrese un puntero a esta dirección
  • Si el desarrollo falla, se devuelve un puntero NULL, por lo que se debe verificar el valor devuelto
  • El tipo de valor devuelto es void*, que se puede forzar según nuestras necesidades

Función gratuita : se utiliza específicamente para liberar y recuperar memoria dinámica.

原型 : vacío libre (void * ptr)

  • Si ptr no es desarrollado por la memoria dinámica, las operaciones como la función libre no están definidas
  • Si ptr es un puntero NULL, la función no funcionará

Si el espacio solicitado no está libre (se olvidó de liberarlo): causará una pérdida de memoria.
Las pérdidas de memoria pueden hacer que la memoria del sistema disminuya. Si el programa se cierra, la pérdida de memoria se recuperará automáticamente y la memoria volverá al sistema.

Los programas que se ejecutan la mayor parte del tiempo deben prestar especial atención a las pérdidas de memoria.

Un puntero apunta a un espacio que no tiene permiso de uso. Estos punteros se denominan punteros salvajes (punteros colgantes).

int main()
{
	int num = 5;
	int *ptr = NULL;
	ptr = (int *)malloc(sizeof(int)*num);
	if (NULL == ptr)
	{
		exit(EXIT_FAILURE);
	}
	printf("%p\n", ptr);
	free(ptr);
	printf("%p\n", ptr);
	return 0;
}

Inserte la descripción de la imagen aquí
Después de free, ptr todavía apunta a la dirección, pero el puntero no tiene permiso para operar en la dirección.

función calloc

void * calloc (tamaño_t num, tamaño_t tamaño);

  • Cree un espacio para números de elementos de tamaño e inicialice cada sección del espacio a 0

Comparado con la función malloc:

El espacio solicitado por malloc no se inicializará. (Quizás más rápido, porque se ha realizado menos trabajo)
Se inicializará el espacio solicitado por calloc. (Por byte, inicializado a 0)

Al solicitar espacio, generalmente el tamaño real de la aplicación es mayor que el tamaño de espacio de memoria requerido: por
ejemplo, se requieren 8 bytes de espacio, que en realidad es mayor que 8.
¿por qué?

  1. El espacio adicional no es para que lo utilicen los usuarios, sino para la gestión del sistema.
  2. Después de liberar el espacio, el libre albedrío no vaciará ptr. Solo se publica una dirección. Pero después del lanzamiento, no se puede usar y se informará un error si se usa nuevamente. Lo que se libera es la correspondencia entre punteros y direcciones.

 
 
En la gestión de memoria dinámica, toda la aplicación debe aplicarse y liberarse como un todo . No realice cambios en el puntero.

función de reasignación

void * realloc (void * ptr, size_t size)

  • ptr es la dirección de memoria que se va a ajustar
  • el tamaño es el tamaño ajustado
  • El valor de retorno es la dirección de inicio después del ajuste.

¿Cómo ajustar?
Hay dos situaciones para el ajuste de la función de reasignación:

  1. Expansión:

Expansión directa: el espacio original es lo suficientemente grande, se puede expandir directamente y el valor de retorno es el mismo.
Reabrir: (el espacio original es insuficiente), reabrir el espacio y regresar a la nueva dirección
Inserte la descripción de la imagen aquí

int main()
{
	int num = 5;
	int *ptr = NULL;
	ptr = (int *)malloc(sizeof(int)*num);
	if (NULL == ptr)
	{
		exit(EXIT_FAILURE);
	}
	printf("%p\n", ptr);
	int *ret = realloc(ptr, 10000);
	if (NULL != ret)
	{
		ptr = (int *)ret;
	}
	printf("%p\n", ptr);
	free(ptr);
	return 0;
}

Inserte la descripción de la imagen aquí

2. Encogimiento: solo encoge directamente.

Cuando use la función de reasignación, no puede usarla así: asigne directamente el espacio reaplicado al puntero antiguo.
Si lo hace, si el desarrollo falla, la devolución será NULL, el espacio original se establecerá en NULL y este espacio ya no se encontrará. También falta el puntero. El espacio del montón se perderá, lo que provocará una pérdida de memoria. Se puede utilizar una decisión para decidir si hacerlo. Como el código anterior.

Una vez que se ejecuta la función de reasignación, se utiliza el espacio recién aplicado, incluido free. Y ya no uses el espacio antiguo, gratis no libera el espacio antiguo.

 
 
 

Una pregunta más interesante:

char *GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void test()
{
	char *str = NULL;
	str = GetMemory();
	printf(str);
}

La función GetMemory devuelve la dirección inicial de p, que se libera cuando se ajusta. Sin embargo, la dirección de la matriz p, sus datos aún existen.
Esto es lo mismo que almacenar un archivo en una computadora. Cuando se elimina un archivo, se elimina el permiso para usar este bloque. El archivo no es válido, pero sus datos aún existen. La recuperación de datos se basa en esta naturaleza.
Finalmente, cuando se llama a la función printf, se forma una nueva estructura de marco de pila, que sobrescribirá estos datos. Por lo tanto, la salida de este código está distorsionada.

 
 
 
 
En la gestión de memoria dinámica, preste más atención a:

  1. Se debe verificar el espacio solicitado. (Si el desarrollo es exitoso)
  2. Después de su uso, debe liberarse. (De lo contrario, provocará una pérdida de memoria)
  3. No cruce la frontera para visitar.
  4. Free debe liberar el espacio abierto por la memoria dinámica, no en la pila.
  5. La posición inicial no se puede cambiar ni soltar parcialmente.
  6. No lo suelte varias veces (después del primer lanzamiento, el puntero no tiene autoridad de operación en el espacio y, si lo suelta de nuevo, se producirá un error).

Supongo que te gusta

Origin blog.csdn.net/w903414/article/details/106943162
Recomendado
Clasificación