Questão 1:
Qual será o resultado da execução da função Test?
#include<stdio.h>
#include<stdlib.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;
}
Análise do problema: este código irá travar.
Passamos str para a função GetMemory e realizamos a alocação dinâmica de memória em str. Neste momento, str aponta para o espaço p. Observe que p é apenas um parâmetro formal neste momento, portanto, quando o programa sair da função GetMemory, o valor de str não será alterado. Qualquer alteração e, ao mesmo tempo, a memória p alocada dinamicamente não será recuperada, o que causa vazamento de memória.
O programa então entrará na função strcpy. Neste momento, str é NULL. Neste momento, a função strcpy ainda desreferenciará str. Desreferenciar o ponteiro nulo resultará em O programa travou.
Solução: passe o endereço de str e use char**p para recebê-lo. Este método pode efetivamente abrir espaço para str.
#include<stdio.h>
#include<stdlib.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:
Questão 2:
Qual será o resultado da execução da função Test?
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
test();
return 0;
}
Análise do problema: Este código ainda não consegue obter o resultado desejado.
Passamos str para a função GetMemory. A função GetMemory abriu espaço p, mas p existe na área da pilha. Deve-se observar que os dados na área da pilha só são válidos durante a chamada da função. Uma vez que o função retorna, Quando o quadro da pilha é exibido, os dados na área da pilha serão destruídos. Mesmo que o endereço de p seja distribuído, str pode encontrar o endereço do espaço p, mas os dados em p foram destruídos.
solução:
1. Você pode usar static para modificar p para tornar p uma variável estática. Variáveis estáticas têm um ciclo de vida global. Elas existem durante a execução do programa e não serão criadas e destruídas quando a função é chamada e retornada.
2. Claro, também é viável usar malloc para abrir espaço.
Questão 3:
Qual será o resultado da execução da função Test?
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;
}
Análise da questão: Também há um problema com este código: o problema está no fato de que o espaço aberto pelo malloc não é liberado e há um problema de vazamento de memória.
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;
}
Esta é a maneira correta de escrever.
Pergunta 4:
Qual será o resultado da execução da função Test?
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
Test();
return 0;
}
Análise do problema: Também há um problema com este código.
Podemos ver que str foi liberado, mas não foi esvaziado. Como resultado, str ainda aponta para o espaço aberto por malloc, o que causa o problema de ponteiros selvagens. Então strcpy acessará o espaço apontado por str, mas o espaço apontado por str foi liberado, o quecausará acesso ilegal à memória.