Publicidade

Memória Dinâmica (malloc / free)

Alocação dinâmica em C: malloc, free e como prevenir vazamentos de memória.

📖 O que aprender nesta página
✅ Essencial que você precisa saber
  • malloc(bytes) para alocar, free(p) para liberar
  • Verifique o retorno em busca de NULL
  • Toda alocação precisa ser liberada
⭐ Leia se tiver tempo
  • calloc (inicializa com zero), realloc (redimensiona)
  • Vazamentos de memória e detectores
  • Evite ponteiro pendurado: defina p = NULL; após free
💪 É normal não pegar na primeira tentativa
Memória dinâmica adiciona uma responsabilidade de "pegar emprestado e devolver" em cima de ponteiros, então são várias ideias ao mesmo tempo.
Como voltar a isso
  1. Revise ponteiros se ainda se sente inseguro
  2. Pense em malloc (pegar emprestado) e free (devolver) como um par que sempre precisa combinar
  3. Comece com tamanhos pequenos — cerca de 10 elementos — para construir sua intuição
  4. Crie o hábito de definir p = NULL; logo depois de chamar free
  5. Um vazamento de memória não quebra seu programa na hora, então não deixe isso travar seu progresso
💡 Dica: emparelhe todo malloc com um free e sempre faça verificação de NULL no valor de retorno. Isso já é suficiente para começar.

Por que precisamos de memória dinâmica?

Até aqui, arrays tinham seu tamanho fixado em tempo de compilação, como em int a[5];. Mas em programas do mundo real, muitas vezes você não sabe a quantidade de elementos até a execução.
A limitação do array fixo
int a[100];
Não cabe mais do que 100 itens, e se você tem menos, a memória restante é desperdiçada.
Com alocação dinâmica
int *a = malloc(n * sizeof(int));
Aloca exatamente n itens e redimensione conforme necessário.

malloc e free

malloc aloca a quantidade de bytes que você pede e retorna um ponteiro para o início desse bloco. Quando você terminar, libere com free.
#include<stdlib.h>  // necessário para malloc, free

int *p = (int *)malloc(sizeof(int) * 5);
// aloca espaço para 5 ints (= 20 bytes)

if(p == NULL){
  printf("allocation failed\n");
  return 1;
}

// use como um array
for(int i = 0; i < 5; i++){
  p[i] = i * 10;
}

free(p);  // sempre libere quando terminar
sizeof(int) * 5 é 4 × 5 = 20 bytes. malloc trabalha em bytes, então multiplicar por sizeof é o idioma padrão.

Arrays dinâmicos — tamanho decidido em tempo de execução

Um padrão comum é pedir ao usuário uma contagem e então alocar um array exatamente desse tamanho.
int n;
printf("How many? ");
scanf("%d", &n);

int *data = (int *)malloc(sizeof(int) * n);
if(data == NULL) return 1;

for(int i = 0; i < n; i++){
  printf("Item %d: ", i+1);
  scanf("%d", &data[i]);
}

// calcula a soma
int sum = 0;
for(int i = 0; i < n; i++) sum += data[i];
printf("Sum: %d\n", sum);

free(data); // não se esqueça de liberar
p[i] e *(p + i) significam a mesma coisa — um ponteiro vindo de malloc pode ser indexado com [] como um array.

Vazamentos de memória — o que acontece quando você esquece de liberar

Se você esquecer de fazer free na memória obtida por malloc, ela permanece reservada até o programa acabar. Isso é o chamado vazamento de memória.
Simulação de vazamento de memória
Clique nos botões para ver a memória mudar.
Em programas de longa duração (servidores, sistemas embarcados, etc.), vazamentos de memória são fatais. Mesmo pequenos vazamentos se acumulam ao longo do tempo e eventualmente esgotam a memória, derrubando o programa. Crie o hábito: se você faz malloc, você faz free.

🔥 Linha do tempo do heap — visualize o fluxo malloc/free

Veja como o heap muda conforme você chama malloc e free. Avance por cinco cenários para conhecer os bugs clássicos: double-free, use-after-free, vazamento de memória e fragmentação.
🧪 Escolha um cenário
Escolha um cenário para começar.
// Nenhum cenário selecionado
Estado do heap
Em uso: 0 B Pico: 0 B malloc: 0 free: 0
Log de operações
(Escolha um cenário e pressione ▶)
💡 Como ler: cada bloco mostra ID, endereço, tamanho e estado (🟢 em uso ou 🔴 liberado). Operações ilegais como double-free ou use-after-free são sinalizadas em vermelho.

Experimente você mesmo — memória dinâmica

Aloque um array dinâmico, preencha com valores e calcule a soma.
dynamic.c
Saída
Clique em Executar...
💡 Tente também estas ideias
Publicidade

Aulas relacionadas

Avançado
Noções básicas de ponteiros
Entenda ponteiros com visualização de memória.
Algoritmos
Estruturas de dados
Lista encadeada, pilha e fila — implementação e visualização.
Referência
Erros de execução e falhas de segmentação
Causas de falhas de segmentação e como depurar erros de execução.
← Aula anterior
Aula 29: Entrada/Saída de arquivos
Próxima aula →
Aula 31: Estruturas de dados

Perguntas Frequentes

P. Devo usar malloc ou um array?

R. Use um array comum quando o tamanho é conhecido em tempo de compilação, e malloc quando o tamanho só é conhecido em tempo de execução. Se você sabe que o máximo é 100, use um array; se o usuário informa a contagem, use malloc. Arrays geralmente são mais rápidos e mais seguros, então prefira-os quando puder.

P. O que acontece se eu esquecer de chamar free?

R. Você tem um vazamento de memória. A memória alocada fica inalcançável e, em programas de longa duração, a memória disponível diminui aos poucos até o processo ficar sem memória e quebrar. A regra é simples: se você faz malloc, você precisa fazer free. Alocação e liberação sempre precisam andar em par.

P. Qual é a diferença entre malloc e calloc?

R. malloc aloca o tamanho pedido, mas deixa a memória sem inicializar. calloc zera a memória para você. A assinatura é calloc(quantidade, tamanho) — por exemplo, calloc(10, sizeof(int)) aloca 10 ints, todos inicializados em zero.

P. O que é exatamente um vazamento de memória?

R. Um vazamento de memória é memória que foi alocada mas nunca liberada — ela fica desperdiçada até o programa sair. Um vazamento único raramente importa, mas vazamentos dentro de um laço se acumulam e acabam esgotando a memória. Ferramentas como valgrind --leak-check=full são comumente usadas para detectá-los.

Quiz Rápido

Confira sua compreensão desta aula.

Q1. O que acontece se você nunca libera memória obtida com malloc?

Ela é liberada automaticamente
Ocorre um vazamento de memória
Erro de compilação

A memória de malloc precisa ser liberada explicitamente. Se você esquecer, ela vaza.

Q2. O que malloc(sizeof(int) * 10) faz?

Aloca espaço suficiente para 10 ints
Aloca espaço suficiente para 1 int
Aloca exatamente 10 bytes

sizeof(int) * 10 calcula o tamanho em bytes para 10 ints, e malloc aloca essa quantidade de bytes no heap.

Q3. O que você deve fazer com um ponteiro logo após chamar free?

Continuar usando
Atribuir NULL a ele
Nada mais é necessário

Depois de free, o ponteiro vira um "ponteiro pendurado". Defini-lo como NULL facilita detectar qualquer reuso acidental.

Compartilhe este artigo
Compartilhar no X Compartilhar no Facebook