Controlo de Memória Dinâmica
Funções Principais de Alocação de Memória
Função malloc()
Aloca um número especificado de bytes na memória de heap sem inicialização.
void* malloc(size_t size);
Função calloc()
Aloca memória e inicializa todos os bytes com zero.
void* calloc(size_t num_elements, size_t element_size);
Função realloc()
Altera o tamanho de um bloco de memória previamente alocado.
void* realloc(void* ptr, size_t new_size);
Fluxo de Alocação de Memória
graph TD
A[Alocar Memória] --> B{Alocação bem-sucedida?}
B -->|Sim| C[Utilizar Memória]
B -->|Não| D[Lidar com o Erro]
C --> E[Liberar Memória]
Exemplo Prático de Gerenciamento de Memória
#include <stdio.h>
#include <stdlib.h>
int main() {
// Alocação de array dinâmico
int *dynamic_array = NULL;
int size = 5;
// Alocar memória
dynamic_array = (int*) malloc(size * sizeof(int));
if (dynamic_array == NULL) {
printf("Falha na alocação de memória\n");
return 1;
}
// Inicializar o array
for (int i = 0; i < size; i++) {
dynamic_array[i] = i * 10;
}
// Redimensionar o array
dynamic_array = realloc(dynamic_array, 10 * sizeof(int));
if (dynamic_array == NULL) {
printf("Falha na realocação de memória\n");
return 1;
}
// Liberar memória
free(dynamic_array);
return 0;
}
Estratégias de Alocação de Memória
| Estratégia |
Descrição |
Caso de Uso |
| Alocação Antecipada |
Alocar toda a memória necessária de antemão |
Estruturas de tamanho fixo |
| Alocação Preguiçosa |
Alocar memória conforme necessário |
Estruturas de dados dinâmicos |
| Alocação Incremental |
Aumentar gradualmente a memória |
Coleções em crescimento |
Técnicas Comuns de Controlo de Memória
1. Verificações de Ponteiros Nulo
Sempre verifique se a alocação de memória foi bem-sucedida.
2. Rastreio de Limites de Memória
Acompanhe o tamanho da memória alocada.
3. Evitar Dupla Liberação
Nunca libere o mesmo ponteiro duas vezes.
4. Definir Ponteiros para NULL
Após a liberação, defina os ponteiros para NULL.
Gerenciamento Avançado de Memória
Pools de Memória
Pré-alocar um grande bloco de memória e gerenciar sub-alocações.
Alocações Personalizadas
Implementar gerenciamento de memória específico da aplicação.
Possíveis Armadilhas
- Vazamentos de memória
- Ponteiros pendentes
- Transbordamentos de buffer
- Fragmentação
Ferramentas de Depuração
- Valgrind
- AddressSanitizer
- Profissionais de memória
Conclusão
O controlo eficaz de memória dinâmica requer planeamento cuidadoso e práticas consistentes. LabEx recomenda o aprendizado contínuo e a prática para dominar estas técnicas.