Explicación detallada de los conceptos básicos de la gestión de memoria dinámica

Tabla de contenido

1. Por qué hay una asignación de memoria dinámica

2. Introducción a las funciones de memoria dinámica

2.1 malloc y gratis

Función:

Parámetros y valores de retorno:

Precauciones:

consejo:

2.2 llamada

 2.3 Función de reasignación

Función:

Parámetros y valores de retorno:

Dos casos de realloc abriendo espacio

realloc tomará las siguientes medidas para

Pregunta: ¿Se puede aceptar el valor de retorno de realloc con el puntero original?

3. Errores comunes de memoria dinámica

3.1 Operación de desreferenciación en puntero NULL

3.2 Acceso fuera de límites al espacio abierto dinámico

3.3 Liberación gratuita de memoria asignada no dinámicamente

3.4 Usar gratis para liberar parte de una memoria asignada dinámicamente

3.5 Múltiples liberaciones de una misma memoria dinámica

3.6 Abre memoria dinámicamente y olvídate de liberar (pérdida de memoria) se debe liberar el espacio abierto


1. Por qué hay una asignación de memoria dinámica

Los métodos de desarrollo de memoria que hemos dominado son:

int a = 0;
char b[10] = {0};

Sin embargo, la forma de apertura del espacio antes mencionada tiene dos características:

  1. El tamaño del espacio abierto es fijo.
  2. Cuando se declara una matriz, se debe especificar la longitud de la matriz y la memoria que necesita se asigna en el momento de la compilación.

Pero la demanda de espacio no es sólo la situación anterior. A veces, el tamaño del espacio que necesitamos se conoce cuando el programa se está ejecutando .

La forma de abrir espacio al compilar la matriz no es satisfactoria.

En este momento, solo se puede utilizar el desarrollo de memoria dinámica.

2. Introducción a las funciones de memoria dinámica

2.1 malloc y gratis

El lenguaje C proporciona una función de desarrollo de memoria dinámica - malloc

Función:

Solicite un espacio disponible continuo de la memoria y devuelva un puntero a este espacio.

Parámetros y valores de retorno:

El parámetro es un entero sin signo en bytes, y el valor devuelto es void*, que apunta al puntero que abrimos en este espacio.

Precauciones:
  • Si la asignación es exitosa, se devuelve un puntero al espacio asignado.
  • Si la apertura falla, se devuelve un puntero NULL, por lo que se debe comprobar el valor de retorno de la función malloc .
  • El tipo del valor devuelto es void*, por lo que la función malloc no conoce el tipo de espacio abierto, y el uso específico lo decide el usuario.
  • Si el tamaño del parámetro es 0, el comportamiento de malloc no está definido por el estándar.
consejo:
  • Después de que malloc solicita el espacio, devuelve directamente la dirección de inicio del espacio sin inicializar el contenido del espacio.
  • El espacio de memoria solicitado por malloc se devuelve al sistema operativo cuando el programa sale.Cuando el programa no sale, la memoria dinámicamente enojada no se liberará activamente y debe liberarse con la función libre .
  • Cada vez que la función gratuita libera el espacio, el puntero no tiene contenido puntiagudo. Para evitar punteros salvajes, debe establecerse en control (es decir, después de cada uso de la función gratuita, debe establecerse en un puntero nulo )
  • La función gratuita no puede liberar espacio de memoria asignado no dinámicamente, este comportamiento no está definido por el estándar
  • Si el parámetro de la función libre es un puntero nulo, la función libre no hace nada
int main()
{
	//int arr[10];
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	//开辟成功
	for (int i=0;i<10;i++)
	{
		printf("%d\n", *(p + 1));
	}
    free(p);
    p=NULL;
	return 0;
}

2.2 llamada

El lenguaje C también proporciona una función llamada calloc, que también se utiliza para la asignación dinámica de memoria.El prototipo es el siguiente:

  •  La función de la función es abrir un espacio para num elementos de tamaño size e inicializar cada byte del espacio a 0.
  • La única diferencia con la función malloc es que calloc inicializará cada byte de la aplicación a 0 antes de devolver la dirección.

Por ejemplo:

 2.3 Función de reasignación

Función:

La aparición de la función realloc hace que la gestión de la memoria dinámica sea más flexible y ajusta el tamaño de la memoria dinámica.

Parámetros y valores de retorno:

ptr es la dirección de memoria que se va a ajustar, size es el nuevo tamaño después del ajuste (en bytes) y el valor de retorno es la posición inicial de la memoria después del ajuste. Si ptr es un puntero nulo, la función de la función es la misma que la función malloc.

Dos casos de realloc abriendo espacio

1. Hay suficiente espacio detrás del espacio original

Devolver directamente la dirección inicial del espacio original

2. No hay suficiente espacio detrás del espacio original

realloc tomará las siguientes medidas para

(1) Abrir un nuevo espacio

(2), los datos del antiguo espacio se copiarán en el nuevo espacio

(3), libera el viejo espacio

(4), devuelve la dirección inicial del nuevo espacio

Pregunta: ¿Se puede aceptar el valor de retorno de realloc con el puntero original?

Respuesta: No, porque si realloc no aumenta la capacidad , devolverá un puntero nulo, y el espacio señalado por el puntero original no se ha liberado, por lo que se establecerá como un puntero nulo, lo que provocará una pérdida de memoria . Por lo tanto, deberíamos usar un nuevo puntero para aceptarlo y luego juzgar si el aumento de capacidad es exitoso.Si es exitoso, asigne el contenido del nuevo puntero al puntero original, de lo contrario, el programa finaliza.

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		perror(malloc);
		return 1;
	}
	for (int i=0;i<2;i++)
	{
		*p = i + 1;
		p++;
		//p[i]=i+1;
	}
	int* ret = (int*)realloc(p, 80);
	if (ret == NULL)
	{
		perror(realloc);
		return 1;
	}
	p = ret;
	for (int i=0;i<20;i++)
	{
		printf("%d\n", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

 Lo anterior es la forma correcta de usar realloc para aumentar la capacidad. Si se reduce la capacidad, ingrese directamente un valor más pequeño que el tamaño original.

3. Errores comunes de memoria dinámica

3.1 Operación de desreferenciación en puntero NULL

Solución: determine si el valor de retorno de la función de asignación de memoria malloc/calloc/realloc está vacío

3.2 Acceso fuera de límites al espacio abierto dinámico

3.3 Liberación gratuita de memoria asignada no dinámicamente

3.4 Usar gratis para liberar parte de una memoria asignada dinámicamente

 Tenga en cuenta que p en este momento no apunta a la dirección de inicio de nuestro espacio abierto dinámico, sino que es equivalente a una parte de la memoria dinámica. En este momento, es incorrecto usar free to release. Free release debe comenzar desde el principio dirección de la memoria dinámica !

¡No permita que el puntero de inicio se desvíe! 

3.5 Múltiples liberaciones de una misma memoria dinámica

3.6 Abre memoria dinámicamente y olvídate de liberar (pérdida de memoria) se debe liberar el espacio abierto

Solución:

El espacio solicitado por la memoria dinámica no se destruirá automáticamente cuando se salga del alcance, solo hay dos formas de destruirlo (devolver la memoria al sistema operativo): salir del programa y la función libre.

¡Las funciones malloc y free se usan en parejas !

Supongo que te gusta

Origin blog.csdn.net/hanwangyyds/article/details/131839879
Recomendado
Clasificación