04. Alocação Dinâmica com malloc, calloc e free
Descobre como requisitar memória na Heap em tempo de execução, redimensionar blocos e evitar memory leaks graves.
Alocação Dinâmica com malloc, calloc e free
Quando declaras um vetor normal em C clássico (ex: int v[100];), o seu tamanho fica fixado na compilação e a memória é alocada na Stack.
Mas e se o teu programa só souber o número de elementos durante a execução (por exemplo, lendo um ficheiro ou input do utilizador)? É aqui que entra a Heap e as funções de <stdlib.h>.
As Quatro Funções Vitais de <stdlib.h>
malloc(size_t size): Reserva um bloco contínuo desizebytes. O conteúdo da memória vem com “lixo” inicial.calloc(size_t num, size_t size): Reserva memória paranumelementos e inicializa todos os bytes a zero.realloc(void *ptr, size_t new_size): Redimensiona um bloco previamente alocado.free(void *ptr): Devolve a memória ao sistema operativo quando já não precisas dela.
Exemplo: Criar um Vetor com Tamanho Decidido pelo Utilizador
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
printf("Quantos números queres guardar? ");
if (scanf("%d", &n) != 1 || n <= 0) {
printf("Valor inválido!\n");
return 1;
}
// 1. Alocar memória na Heap: n * tamanho de um int
int *array = (int *)malloc(n * sizeof(int));
// 2. SEMPRE verificar se o malloc devolveu NULL (falta de memória)
if (array == NULL) {
fprintf(stderr, "Erro crítico: Memória insuficiente!\n");
return 1;
}
// 3. Preencher o vetor normalmente como se fosse um array comum
for (int i = 0; i < n; i++) {
array[i] = (i + 1) * 10;
}
// 4. Mostrar os valores
printf("\nValores alocados na Heap:\n");
for (int i = 0; i < n; i++) {
printf("array[%d] = %d\n", i, array[i]);
}
// 5. REGRA DE OURO: Liberar a memória para evitar Memory Leak!
free(array);
array = NULL; // Boa prática para evitar dangling pointer
printf("\nMemória libertada com sucesso!\n");
return 0;
}
O Que Acontece Se Esqueceres o free()?
Se alocares memória repetidamente num ciclo ou aplicação de longa duração sem a libertar, ocorre uma fuga de memória (Memory Leak). A aplicação consumirá gradualmente toda a memória RAM disponível até ser terminada à força pelo sistema operativo.
Ferramenta Essencial: Valgrind
Para detetar fugas de memória no Linux ou WSL:
gcc -g main.c -o main
valgrind --leak-check=full ./main
O Valgrind dirá com precisão cirúrgica a linha onde esqueceste o free()!