Gerenciamento dinâmico de memória (continuação) + arrays flexíveis

contente

1. Várias perguntas de teste escrito

1.1 Tópico 1:

 1.2 Tópico 2

1.3 Tópico 3

1.4 Pergunta 4

2. Revisão do Gerenciamento Dinâmico de Memória

 3. Matriz flexível

 3.1 Recursos de Arrays Flexíveis

 3.2 O uso de arrays flexíveis

3.3 Vantagens de arrays flexíveis 


1. Várias perguntas de teste escrito

1.1 Tópico 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 da operação

Como p é um parâmetro formal , a função GetMemory será destruída depois que o espaço for aberto. Neste momento, nenhum ponteiro pode encontrar o endereço do espaço aberto, causando um problema de vazamento de memória . Portanto, str ainda é NULL e strcpy precisa a ser desreferenciado ao implementar strcpy.(desreferenciando NULL) haverá um problema (acesso ilegal à memória) e o programa irá travar.

A implementação do strcpy pode se referir à string da linguagem C + função de memória - Programador procurado 

Nota : Não há problema com o printf(str) escrevendo aqui, mas não pode ser impresso devido aos motivos acima.

Por exemplo: printf("abc") na verdade passa o endereço do primeiro elemento a para a função printf, char *str="abc", str armazena o endereço do primeiro elemento de "abc", que é equivalente ao array name, então printf (str) é razoável.

Emenda um

#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;
}

executar captura de tela

Alteração dois

#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 Tópico 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;
}

Após a execução da função GetMemory, o espaço "helloworld" foi liberado e p não tem permissão para usá-lo. É um ponteiro curinga. Quando este espaço é acessado novamente, este espaço pode ter sido substituído (espaço de acesso ilegal)

Por exemplo: Por exemplo, Li Hua está cansado do trabalho e não quer ir para casa descansar. Ele encontra um hotel do lado de fora e o quarto é 509. Por estar muito cansado, ele dorme um pouco. Acontece que Li O amigo estrangeiro de Hua, John, vai visitar o lugar amanhã. , Se você quiser encontrar um lugar para morar, basta ligar para Li Hua. Li Hua: Ok, você pode vir e ficar amanhã. Estou no 509. Quando eu me levantar, no dia seguinte, Li Hua sairá do quarto. John ouviu Li Hua dizer ontem. Posso ficar no 509, então arrastei minha bagagem para o hotel e disse: quero ficar no 509, mas o quarto já está ocupado... ...

 Modificação: modificação 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 Tópico 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;
}

Depois que o espaço aberto dinamicamente for usado, use free para liberá-lo e esvazie o ponteiro

mudar a lei

#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 Pergunta 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;
}

executar captura de tela

 mudar a lei

#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. Revisão do Gerenciamento Dinâmico de Memória

Gerenciamento dinâmico de memória da linguagem c - blog de Zhen Bailinzi - blog CSDN

 3. Matriz flexível

O último elemento na estrutura pode ser um array de tamanho desconhecido , chamado de membro de array flexível

Por exemplo: 

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

 Alguns compiladores relatam erros, você pode tentar a seguinte maneira de escrever.

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

 3.1 Recursos de Arrays Flexíveis

  1. Um membro de matriz flexível em uma estrutura deve ser precedido por pelo menos um outro membro . caso contrário, o tamanho da estrutura é 0
  2. O tamanho dessa estrutura retornada por sizeof não inclui a memória do array flexível.
  3. As estruturas que contêm membros de matriz flexíveis usam a função malloc() para alocar memória dinamicamente, e a memória alocada deve ser maior que o tamanho da estrutura para acomodar o tamanho esperado da matriz flexível.

 por exemplo:

#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 O uso de arrays flexíveis

#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;
}

Outra maneira de escrever semelhante a arrays flexíveis 

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;

 A diferença entre os dois é

1. O tamanho da estrutura onde a matriz flexível está localizada é 4 e o tamanho da estrutura a seguir é 8

2. Arrays flexíveis existem apenas em estruturas, e o método a seguir é geral (abre espaço de memória dinamicamente)

3.3 Vantagens de arrays flexíveis 

1. Liberação de memória conveniente
Se nosso código estiver em uma função que é usada por outras pessoas, você faz uma alocação de memória secundária nele e retorna toda a estrutura para o usuário. O usuário pode liberar a estrutura chamando free, mas o usuário não sabe que os membros da estrutura também precisam ser livres, então você não pode esperar que o usuário descubra. Portanto, se alocarmos a memória da estrutura e a memória requerida por seus membros de uma só vez, e retornarmos um ponteiro de estrutura para o usuário, o usuário poderá liberar toda a memória fazendo um free uma vez .
2. Propício à velocidade de acesso .
A memória contígua é benéfica para melhorar a velocidade de acesso e reduzir a fragmentação da memória

Como o espaço aberto pelo uso múltiplo de malloc não é necessariamente contínuo, haverá algumas lacunas no meio, e chamamos essas lacunas de fragmentação de memória

A capacidade dos blogueiros é limitada, se houver algum mal-entendido, você pode criticar o caldo de ferro.

Por hoje é só, obrigado por assistir

Acho que você gosta

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