C++: Alocação Dinâmica de Memória

Última atualização: 2026-08-26

Nas aulas anteriores, variáveis e arrays eram alocados na pilha — tamanho fixo, liberados automaticamente quando a função termina.

Mas se você precisa armazenar uma quantidade incerta de dados (ex: o usuário digita 1000 inteiros, mas você não sabe no momento da compilação), você precisa de alocação dinâmica de memória — alocando memória no heap.



1. Pilha vs Heap

(1) 1.1 Duas Regiões de Memória

Comparação Pilha (Stack) Heap
Momento da alocação Determinado em tempo de compilação Determinado em tempo de execução
Tamanho Fixo (determinado em tempo de compilação) Variável (solicitado em tempo de execução)
Momento da liberação Automático (quando a função termina) Manual (usando delete)
Eficiência Alta Baixa
Casos de uso Variáveis locais, arrays Dados de tamanho dinâmico

(2) 1.2 Analogia do Dia a Dia

Analogia da Vida Real Equivalente em Programa
Restaurante de fast food (cardápio fixo, comida servida imediatamente após o pedido) Pilha
Buffet (pegue o quanto quiser) Heap


2. new e delete

(1) 2.1 Alocando Memória com new

Sintaxe:

▶ Exemplo 2: Gerenciamento Dinâmico de Memória (Dificuldade ⭐)

TEXT 📖 Somente leitura
Type* nomePonteiro = new Type;

Saída:

TEXT 📖 Somente leitura
(Saída do programa)

Exemplo:

CPP
#include <iostream>

int main() {
 // Aloca um int no heap
 int* p = new int; // p Apontando para int no heap
 
 *p = 5; // Atribui valor ao int no heap
 std::cout << "*p = " << *p << std::endl; // 5
 
 return 0;
}

💡 Ponto-chave: new retorna um ponteiro — apontando para a memória alocada no heap.


(2) 2.2 Liberando Memória com delete

Sintaxe:

TEXT 📖 Somente leitura
delete nomePonteiro;

Exemplo:

CPP
#include <iostream>

int main() {
 int* p = new int;
 *p = 5;
 
 std::cout << "*p = " << *p << std::endl;
 
 delete p; // ✅ Libera memória do heap
 p = nullptr; // ✅ Boa prática:Definir como nullptr após liberar
 
 return 0;
}

💡 Regra de ouro: new e delete devem sempre vir em pares — todo new precisa de um delete.


(3) 2.3 Esquecer delete Causa Vazamento de Memória

Exemplo de erro:

CPP
#include <iostream>

void foo() {
 int* p = new int;
 *p = 5;
 // ❌ Esqueceu de escrever delete p;
} // Função termina, p é destruído, mas o int no heap não é liberado (vazamento de memória)

int main() {
 for (int i = 0; i < 1000000; i++) {
 foo(); // Cada chamada vaza 4 bytes
 }
 // Uso de memória do programa continua crescendo, pode eventualmente falhar
 return 0;
}

💡 Vazamento de memória: Memória alocada no heap que nunca é liberada e não pode mais ser acessada (porque o ponteiro para ela foi destruído).



3. Arrays Dinâmicos

(1) 3.1 Alocando Arrays com new

Sintaxe:

TEXT 📖 Somente leitura
Type* nomePonteiro = new Type[tamanho];

Exemplo:

CPP
#include <iostream>

int main() {
 int n;
 std::cout << "Por favor, digite o tamanho do array: ";
 std::cin >> n;
 
 // Aloca um array de n ints no heap
 int* arr = new int[n];
 
 // Usando o array
 for (int i = 0; i < n; i++) {
 arr[i] = i + 1;
 }
 
 // Exibe o array
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 // Libera array(Nota:Use delete[], não delete)
 delete[] arr;
 
 return 0;
}

💡 Ponto-chave: Para liberar um array, use delete[] (com colchetes), não delete!


(2) 3.2 new e delete Devem Ser Emparelhados Corretamente

Alocação Liberação
new int delete p;
new int[10] delete[] p;

Exemplo de erro:

CPP
int* p = new int[10];
delete p; // ❌ Erro: Deveria usar delete[] p;


4. Ponteiros Pendentes

(1) 4.1 O que é um Ponteiro Pendente?

Um ponteiro pendente é um ponteiro que aponta para memória já liberada.

CPP
#include <iostream>

int main() {
 int* p = new int(5);
 delete p; // Libera memória
 
 // ❌ Perigoso: p agora é um ponteiro pendente
 std::cout << *p << std::endl; // Comportamento indefinido! Pode exibir lixo ou falhar
 
 return 0;
}

💡 Solução: Defina o ponteiro como nullptr imediatamente após liberar:

CPP
delete p;
p = nullptr; // ✅ Boa prática


5. Prática: Ordenando um Array Dinâmico

▶ Exemplo 1: Selection Sort com Array Dinâmico (Dificuldade ⭐⭐)

CPP
#include <iostream>

void selectionSort(int* arr, int n) {
 for (int i = 0; i < n - 1; i++) {
 int minIdx = i;
 for (int j = i + 1; j < n; j++) {
 if (arr[j] < arr[minIdx]) {
 minIdx = j;
 }
 }
 int temp = arr[i];
 arr[i] = arr[minIdx];
 arr[minIdx] = temp;
 }
}

int main() {
 int n;
 std::cout << "Por favor, digite o tamanho do array: ";
 std::cin >> n;
 
 int* arr = new int[n]; // Aloca array dinamicamente
 
 std::cout << "Por favor, digite " << n << " Inteiros: " << std::endl;
 for (int i = 0; i < n; i++) {
 std::cin >> arr[i];
 }
 
 selectionSort(arr, n); // Ordena
 
 std::cout << "Após ordenação: " << std::endl;
 for (int i = 0; i < n; i++) {
 std::cout << arr[i] << " ";
 }
 std::cout << std::endl;
 
 delete[] arr; // Libera memória
 arr = nullptr;
 
 return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Por favor, digite o tamanho do array: 
Por favor, digite  Inteiros: 
Após ordenação: 
 

Resultado da execução:

TEXT 📖 Somente leitura
Por favor, digite o tamanho do array: 5
Por favor, digite 5 Inteiros: 
5 3 1 4 2
Após ordenação: 
1 2 3 4 5


6. Erros Comuns

(1) 6.1 Double delete

Exemplo de erro:

CPP
int* p = new int(5);
delete p;
delete p; // ❌ Erro: Liberação dupla da mesma memória (comportamento indefinido)

Correção: Defina como nullptr imediatamente após liberar (delete nullptr é seguro).

TEXT 📖 Somente leitura
delete p;
p = nullptr;

(2) 6.2 Esquecer delete

Exemplo de erro:

CPP
int* arr = new int[10];
// ❌ Esqueceu de escrever delete[] arr;

Consequência: Vazamento de memória.


❓ Perguntas Frequentes

P: Por que usar memória dinâmica? Não posso simplesmente usar arrays? R: Se você sabe o tamanho em tempo de compilação, arrays funcionam. Mas se: > - O tamanho é determinado pela entrada do usuário > - O tamanho pode ser muito grande (excedendo a capacidade da pilha) > - Você precisa que os dados persistam após o término de uma função

Então você precisa de memória dinâmica.

P: Qual a diferença entre delete e delete[]? R:> - delete libera um único objeto > - delete[] libera um array

Se emparelhado incorretamente (ex: new int[10] com delete p), o comportamento é indefinido (pode liberar apenas o primeiro elemento, ou falhar).

P: Como posso evitar vazamentos de memória? R:> 1. Garanta que new e delete venham em pares > 2. Defina o ponteiro como nullptr imediatamente após liberar > 3. Use smart pointers (std::unique_ptr, std::shared_ptr, coberto mais tarde) — eles liberam memória automaticamente


▶ Exemplo 3: Array Dinâmico (Dificuldade ⭐)

CPP
#include <iostream>

int main() {
    int size = 5;
    int* arr = new int[size];

    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }

    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    delete[] arr;

    return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
0 10 20 30 40
💡 Dica: new int[n] aloca um array, delete[] libera um array. Não esqueça o []!



📖 Resumo

📝 Exercícios

  1. Básico (Dificuldade ⭐): Use new para alocar um double, atribua 3.14, exiba-o, depois libere-o.

  2. Intermediário (Dificuldade ⭐⭐): Deixe o usuário digitar n, use new para alocar dinamicamente um array int de tamanho n, digite n inteiros, encontre o máximo, depois libere a memória.

  3. Desafio (Dificuldade ⭐⭐⭐): Implemente uma classe "array dinâmico" usando memória dinâmica (você aprenderá classes mais tarde; use uma struct por enquanto):

  4. Inclua: int* data (ponteiro para array no heap), int size (tamanho atual), int capacity (capacidade)

  5. Implemente uma função push_back: se size == capacity, realoque um bloco maior de memória (new um array maior, copie os dados, libere o antigo)

  6. Teste: adicione 100 elementos


7. 🚀 Próximo Passo

Agora que você aprendeu alocação dinâmica de memória, vamos avançar para Ponteiros e Referências: Prática Abrangente (Aula 27) — reforçando tudo o que você aprendeu através de exemplos integrados!

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%