Gestión de memoria dinámica (continuación) + arreglos flexibles

contenido

1. Varias preguntas de prueba escrita

1.1 Tema 1:

 1.2 Tema 2

1.3 Tema 3

1.4 Pregunta 4

2. Revisión de la gestión de memoria dinámica

 3. Matriz flexible

 3.1 Características de los arreglos flexibles

 3.2 El uso de arreglos flexibles

3.3 Ventajas de los arreglos flexibles 


1. Varias preguntas de prueba escrita

1.1 Tema 1:

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void GetMemory(char* p) 
{
	p = (char*)malloc(100);
}
void Test(void) 
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
}
int main()
{
    Test();
    return 0;
}

resultado de la operación

Dado que p es un parámetro formal , la función GetMemory se destruirá después de que se abra el espacio. En este momento, ningún puntero puede encontrar la dirección del espacio abierto, lo que provoca un problema de fuga de memoria . Por lo tanto, str sigue siendo NULL y strcpy necesita para ser desreferenciado al implementar strcpy (desreferenciando NULL) habrá un problema (acceso ilegal a la memoria) y el programa fallará.

La implementación de strcpy puede referirse a la cadena de lenguaje C + función de memoria - Se busca programador 

Nota : No hay ningún problema con la escritura de printf(str) aquí, pero no se puede imprimir debido a las razones anteriores.

Por ejemplo: printf("abc") en realidad pasa la dirección del primer elemento a a la función printf, char *str="abc", str almacena la dirección del primer elemento de "abc", que es equivalente a la matriz nombre, por lo que printf (str) es razonable.

Enmienda uno

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

ejecutar captura de pantalla

enmienda dos

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* GetMemory(char* p)
{
	*p = (char*)malloc(100);
    return p;
}
void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	Test();
	return 0;
}

 1.2 Tema 2

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* GetMemory(void) 
{
	char p[] = "hello world";//这块空间是在栈区开辟的,出函数后空间自动销毁
	return p;
}
void Test(void) 
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}

Después de ejecutar la función GetMemory, el espacio "helloworld" se ha liberado y p no tiene permiso para usarlo. Es un puntero salvaje. Cuando se accede de nuevo a este espacio, es posible que se haya sobrescrito (espacio de acceso ilegal)

Por ejemplo: Por ejemplo, Li Hua está cansado del trabajo y no quiere ir a casa a descansar. Encuentra un hotel afuera y la habitación es 509. Debido a que está demasiado cansado, duerme un rato. Sucede que Li El amigo extranjero de Hua, John, visitará el lugar mañana. Si quieres encontrar un lugar para vivir, solo llama a Li Hua. Li Hua: Está bien, puedes venir y quedarte mañana. Estoy en 509. Cuando me levante Al día siguiente, Li Hua dejará la habitación. John escuchó a Li Hua decir ayer. Puedo quedarme en el 509, así que arrastré mi equipaje al hotel y dije: Quiero quedarme en el 509, pero la habitación ya está ocupada... ...

 Modificación: modificación estática

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* GetMemory(void) 
{
	static char p[] = "hello world";//静态区
	return p;
}
void Test(void) 
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}

1.3 Tema 3

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void) 
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
int main()
{
	Test();
	return 0;
}

Después de que se agote el espacio abierto dinámicamente, use gratis para liberarlo y vaciar el puntero

cambiar la ley

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void GetMemory(char** p, int num)
{
    
	*p = (char*)malloc(num);
}
void Test(void) 
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
    free(str);
    str=NULL;
}
int main()
{
	Test();
	return 0;
}

1.4 Pregunta 4

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);//hello所在的空间已经还给操作系统,此时str为野指针
    //free之后,一定要将指针置空
	if (str != NULL)
	{
		strcpy(str, "world");//world会把hello覆盖,(非法访问)
		printf(str);
	}
}
int main()
{
	Test();
	return 0;
}

ejecutar captura de pantalla

 cambiar la ley

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
    str=NULL;
    if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	Test();
	return 0;
}

2. Revisión de la gestión de memoria dinámica

Gestión de memoria dinámica del lenguaje c - Blog de Zhen Bailinzi - Blog de CSDN

 3. Matriz flexible

Se permite que el último elemento de la estructura sea un arreglo de tamaño desconocido , llamado miembro de arreglo flexible .

P.ej: 

struct s1
{
	int age;
	char name[20];
	int arr[];//柔性数组成员
};

 Algunos compiladores informarán errores, puede probar la siguiente forma de escritura.

struct s2
{
	int age;
	char name[20];
	int arr[0];//柔性数组成员,这里的0代表未知大小
};

 3.1 Características de los arreglos flexibles

  1. Un miembro de matriz flexible en una estructura debe estar precedido por al menos otro miembro . de lo contrario, el tamaño de la estructura es 0
  2. El tamaño de esta estructura devuelta por sizeof no incluye la memoria de la matriz flexible.
  3. Las estructuras que contienen miembros de arreglos flexibles usan la función malloc() para asignar memoria dinámicamente, y la memoria asignada debe ser mayor que el tamaño de la estructura para acomodar el tamaño esperado del arreglo flexible.

 p.ej:

#include<stdio.h>
struct s2
{
	int age;//4
	char name[20];//20
	int arr[0];//0
};
int main()
{
	printf("%d\n", sizeof(struct s2));
	return 0;
}

 3.2 El uso de arreglos flexibles

#include<stdio.h>
#include<stdlib.h>
struct s3//4
{
	int num;
	int arr[];
};
int main()
{
	struct s3* ps = (struct s3*)malloc(sizeof(struct s3) + 40);//假设我们希望数组中有10个元素
	ps->num = 100;
	int i = 0;
	//使用
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//增容
	struct s3* ptr = realloc(ps, sizeof(struct s3) + 80);
	if (ptr != NULL)
	{
		ps = ptr;
	}
	for (i = 10; i < 20; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 20; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	//释放
	free(ps);
	ps = NULL;//置空
	return 0;
}

Otra forma de escribir similar a las matrices flexibles 

struct s3//sizeof计算为8
{
	int num;
	int *arr;
};
int main()
{
	struct s3* ps = (struct s3*)malloc(sizeof(struct s3));
	ps->arr = (int*)malloc(sizeof(int) * 5);
	int i = 0;
	//使用
	for (i = 0; i < 5; i++)
	{
		ps->arr[i] = i;
	}
	//增容
	int * ptr = realloc(ps->arr, 10*sizeof(int));
	if (ptr != NULL)
	{
		ps->arr = ptr;
	}
	for (i = 5; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	//释放
	free(ps->arr);
	free(ps);
	ps = NULL;//置空
	return 0;

 La diferencia entre los dos es

1. El tamaño de la estructura donde se encuentra la matriz flexible es 4, y el tamaño de la siguiente estructura es 8

2. Los arreglos flexibles solo existen en estructuras, y el siguiente método es general (abre espacio de memoria dinámicamente)

3.3 Ventajas de los arreglos flexibles 

1. Conveniente liberación de memoria
Si nuestro código está en una función que utilizan otros, realiza una asignación de memoria secundaria y devuelve la estructura completa al usuario. El usuario puede liberar la estructura llamando gratis, pero el usuario no sabe que los miembros de la estructura también deben estar libres, por lo que no puede esperar que el usuario se entere. Por lo tanto, si asignamos la memoria de la estructura y la memoria requerida por sus miembros al mismo tiempo, y devolvemos un puntero de estructura al usuario, el usuario puede liberar toda la memoria haciendo una vez libre .
2. Propicio para la velocidad de acceso .
La memoria contigua es beneficiosa para mejorar la velocidad de acceso y reducir la fragmentación de la memoria

Dado que el espacio abierto por el uso múltiple de malloc no es necesariamente continuo, habrá algunos espacios en el medio, y llamamos a estos espacios fragmentación de la memoria.

La capacidad de los bloggers es limitada. Si hay algún malentendido, puede criticar el jugo de hierro.

Eso es todo por hoy, gracias por ver

Supongo que te gusta

Origin blog.csdn.net/weixin_63451038/article/details/123997636
Recomendado
Clasificación