minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
1. Situação básica
O gerenciamento de memória da linguagem C é dividido em duas partes: gerenciamento do sistema e gerenciamento do manual do usuário do programador. A memória gerenciada pelo sistema são principalmente as variáveis (variáveis locais) dentro da função. Esta parte das variáveis entra na memória quando a função está em execução. , o sistema operacional descarrega-o automaticamente da memória. A memória gerenciada manualmente pelo usuário é composta principalmente de variáveis (variáveis globais) que existem ao longo de todo o processo de execução do programa. A área de memória onde esta parte está localizada é chamada de “área de heap”. pelo usuário. Caso você se esqueça de liberá-lo após o uso, ele continuará ocupando memória até ser entregue ao sistema operacional quando o programa for encerrado.
2. ponteiro vazio
O espaço de memória do computador recebe um código de endereço exclusivo e a área de memória especificada pode ser encontrada por meio do ponteiro de memória. Variáveis de ponteiro precisam ter um tipo, por exemplo: int* p=&x declara um ponteiro do tipo int, que aponta para o endereço da variável inteira x. Quando o compilador obtém os dados deste endereço, ele sabe que o tipo int; os dados são armazenados. Quando você não tem certeza de que tipo de dados está armazenado e apenas deseja encontrar primeiro o endereço de memória do bloco, o ponteiro do tipo void é usado. Um ponteiro de tipo void também é chamado de ponteiro de tipo indefinido e pode apontar para qualquer tipo de dados.
Ponteiros do tipo void podem ser convertidos em ponteiros de outros tipos e não há nada de especial em seu uso, exceto que o conteúdo armazenado não pode ser analisado por meio do método "*".
int x = 10; //Declara variável inteira x
void* p = &x; //Declara o ponteiro void e aponta para o endereço de x, indicando que o ponteiro int (&x) é convertido em um ponteiro void.
int* q = p; // ponteiro vazio é convertido novamente em ponteiro inteiro
printf("%in", *q); //Resultado da execução: 10
Preste atenção na diferença entre void* e void: void não tem tipo e, quando usado para declarar uma função, significa que não há valor de retorno enquanto void*, embora não tenha tipo, mas tem um ponteiro, retorna algo;
3. Funções relacionadas ao gerenciamento de memória
1、malloc()
Esta função pode ser lembrada separadamente. m é a abreviatura de memória e alloc é a abreviatura de alocação.
Função: solicitar um bloco de memória contínuo da área heap (lembrete: a memória da área heap precisa ser gerenciada pelo programador e deve ser destruída após o uso. Isso deve ser sempre lembrado no formato de uso: malloc (consulte 1);
Parâmetros: O parâmetro 1 é o tamanho do bloco de memória (um número inteiro não negativo do tipo size_t, o valor de retorno de sizeof é deste tipo)
Valor de retorno: ponteiro void* (usaremos qualquer tipo de ponteiro que usarmos para receber a memória alocada)
Uso: As variáveis declaradas usando a função malloc estão na área heap, portanto, o método de declaração anônima é frequentemente usado, ou seja, em vez de usar o método de endereço de variáveis específicas, malloc retorna diretamente o ponteiro, conforme mostrado abaixo:
int* ptr = (int*) malloc(sizeof(int)); //Uma variável de ponteiro int é declarada na área de heap
A conversão forçada entre parênteses não é necessária. malloc retorna void*, que pode ser recebido com int*.
Precauções:
a. Use a função malloc para incluir<stdlib.h>arquivo de cabeçalho, como contém apenas<stdio.h> Ele compila bem, mas não funciona corretamente, tenha isso em mente.
b. Atribuir valor a ptr: *ptr=1000;.
c. Use malloc em conjunto com free (que você encontrará mais tarde).
d. Malloc pode não ter sucesso na alocação de endereços. Se não tiver sucesso, ele retornará NULL. Por esse motivo, uma instrução if pode ser adicionada para processamento.
e. malloc apenas aloca memória, independentemente da inicialização. Se a inicialização for necessária, outra função precisará ser chamada.
f. A ocasião mais comumente usada para malloc é alocar memória para arrays e estruturas de dados personalizadas.
2、 conjunto de mem()
Função: Atribui um valor inicial a cada byte do bloco de memória apontado por um ponteiro.
Parâmetros: Parâmetro 1 Ponteiro apontando para a memória de destino Parâmetro 2 Conteúdo de atribuição (valor de código ASCII do tipo int ou caractere do tipo char) Parâmetro 3 Número de bytes a serem atribuídos (tipo size_t)
Valor de retorno: Retorna o ponteiro apontado para a memória de destino. Não faz sentido receber, igual ao parâmetro 1.
Uso: memset(ptrDestMem,'A',sizeof(char)*1024) //Atribuir o caractere A a cada byte de um bloco de memória com comprimento de 1024 bytes
Precauções:
a. O arquivo de cabeçalho ao qual esta função pertence é.<string.h> , alguns compiladores podem ser usados normalmente sem incluir este arquivo de cabeçalho. Se ocorrer um erro de execução, inclua-o.
b. Observe que memset é uma operação em bytes (não em bits). O parâmetro 3 refere-se a quantos bytes precisam ser atribuídos, que pode ser menor ou igual ao número de bytes na memória de destino, mas não pode exceder o limite.
c. O valor do parâmetro 2 não pode exceder o que pode ser acomodado por um byte (int tipo 255).
2、grátis()
Função: Função emparelhada com malloc, usada para liberar a memória alocada pela função malloc e evitar vazamentos de memória
Parâmetros: ponteiro retornado pela função malloc
Uso: grátis(ptr);
Precauções:
a. Os arquivos de cabeçalho que precisam ser incluídos ao usar o free também são.<stdlib.h> , não se esqueça.
b. A função free só pode ser executada uma vez, e o mesmo endereço de memória não pode ser liberado repetidamente, e o ponteiro liberado não pode ser usado novamente.
c.É melhor escrever primeiro malloc e free em pares e depois inserir outros códigos no meio para evitar esquecimento.
3、realocar()
re, ou seja, novamente, abreviatura de alocação de alocação, juntos significa realocação de memória
Função: Modificar o tamanho do bloco de memória alocado (aumentar ou diminuir).
Parâmetros: Parâmetro 1, ponteiro do bloco de memória original, parâmetro 2, tamanho do bloco de memória após aumentar ou diminuir (tipo ainda size_t)
Valor de retorno: ponteiro void* (pode ser recebido pela variável do tipo ponteiro original)
Uso: void* newPtr=realloc(ptr,sizeof(int)*10);
Precauções:
a. Ao usar a função realloc, ela também precisa ser incluída.<stdlib.h> .
b. O bloco de memória apontado pelo ponteiro original foi substituído pelo novo ponteiro, portanto é o novo ponteiro que deve ser liberado quando o programa terminar, e o ponteiro original não precisa ser liberado, caso contrário ocorrerá um erro de operação. ocorrer.
c. realloc pode falhar ao alocar memória e retornar NULL se falhar, então é melhor adicionar uma instrução if para lidar com isso.
4. Exemplos de aplicação
- #include<stdio.h>
- #include<stdlib.h> //malloc、free、realloc
- #include<string.h> //memset
- int main(void)
- {
- //A void指针的使用
- float PI = 3.14159;
- void* pPI = &PI;
- float r = 2.5;
- printf("半径2.5圆的面积:%fn", r * r * *(float*)pPI);//*(float*)pPI—pPI强转为float指针后再解出指向的值
- //B malloc、memset、free函数使用
- int n = 8;
- void* pMyMem = malloc(sizeof(char)*n); //char占1字节,malloc分派n字节的内存,返给void指针
- if (pMyMem == NULL)return 0; //若分派内存失败,程序结束
- void* myMem2=memset(pMyMem,'B',sizeof(char)*8); //对malloc分派的内存区块个字节都写入字符'B'。
- //并用myMem2接收返回的指针
- if (pMyMem == myMem2)printf("memset写入区块指针与其返回的指针相同n");
- char* transCh = pMyMem; //将void指针转成char型指针
- printf("显示写入内容:");
- for (int i = 0; i < n; i++)
- {
- printf("%c ", *transCh); //显示写入的字符
- transCh++;
- }
- printf("n");//换行
- free(pMyMem); //释放malloc函数分派的内存
- //free(ch); //只有malloc分派的内存才需要释放,且只释放一次(这里会报错)
- //C realloc、free函数的使用
- int* pMem = malloc(sizeof(int)*5);
- if (pMem == NULL)return 0;
- for (int i = 0; i < 5; i++) pMem[i] = (i+1)*10;
- for (int i = 0; i < 5; i++) printf("%i ", pMem[i]);
- printf("n重新增加分派内存后n");
- int* newpMem = realloc(pMem, sizeof(int) * 10);
- if (newpMem == NULL)return 0;
- for (int i = 0; i < 10; i++) newpMem[i] = (i + 1) * 10;
- for (int i = 0; i < 10; i++)printf("%i ", newpMem[i]);
- free(newpMem); //释放realloc的内存
- //free(pMem);//pMem已被重置,不能再释放,此语句会造成运行失败
- getchar(); //暂停屏幕
- return 0;
- }