Avançado⏱️ 25 min

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>

  1. malloc(size_t size): Reserva um bloco contínuo de size bytes. O conteúdo da memória vem com “lixo” inicial.
  2. calloc(size_t num, size_t size): Reserva memória para num elementos e inicializa todos os bytes a zero.
  3. realloc(void *ptr, size_t new_size): Redimensiona um bloco previamente alocado.
  4. 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()!