Menu
Coddy logo textTech

Memória Dinâmica (new/delete)

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 14 de 104.

Agora que você entende ponteiros e referências, vamos colocá-los em prática com alocação dinâmica de memória. Os operadores new e delete permitem que você crie e destrua objetos no heap em tempo de execução.

Use new para alocar memória e obter um ponteiro para ela:

int* num = new int;        // Aloca um único inteiro
*num = 42;                 // Atribui valor através do ponteiro

Player* player = new Player("Hero");  // Aloca um objeto

Cada new deve ter um delete correspondente para liberar a memória:

delete num;      // Libera um único objeto
delete player;   // Chama o destrutor e, em seguida, libera a memória

Para arrays, use new[] e delete[]:

int* scores = new int[5];    // Aloca um array de 5 inteiros
scores[0] = 100;

delete[] scores;             // Libera o array - note os colchetes!

Erros comuns a serem evitados:

// Vazamento de memória - esqueceu de deletar
int* ptr = new int(10);
ptr = new int(20);    // Perdeu o acesso à primeira alocação!

// Ponteiro pendente - usando após deletar
delete ptr;
*ptr = 5;             // Comportamento indefinido!

// Delete incompatível
int* arr = new int[10];
delete arr;           // Errado! Deveria ser delete[]

Após a exclusão, defina os ponteiros como nullptr para evitar o reuso acidental. O gerenciamento manual de memória é propenso a erros, razão pela qual o C++ moderno prefere ponteiros inteligentes, que exploraremos a seguir.

challenge icon

Desafio

Fácil

Vamos construir um sistema simples de armazenamento de mensagens que demonstra a alocação dinâmica de memória com new e delete.

Você criará dois arquivos para organizar seu código:

  • MessageBox.h: Defina uma classe MessageBox que gerencia dinamicamente um array de mensagens. A classe deve ter:
    • Um ponteiro privado para um array de strings alocado dinamicamente
    • Um inteiro privado que rastreia a contagem atual de mensagens
    • Um inteiro privado que armazena a capacidade máxima
    • Um construtor que recebe uma capacidade e aloca o array usando new[]
    • Um destrutor que libera adequadamente a memória usando delete[] e imprime "MessageBox destroyed"
    • Um método addMessage(string msg) que adiciona uma mensagem se houver espaço, retornando true em caso de sucesso ou false se estiver cheio
    • Um método printAll() que imprime cada mensagem armazenada em sua própria linha
  • main.cpp: Leia um valor de capacidade e um número de mensagens da entrada. Em seguida, leia essa quantidade de strings de mensagem. Crie um MessageBox na heap usando new, adicione todas as mensagens a ele, chame printAll() e, em seguida, delete adequadamente o MessageBox para liberar memória.

O formato de entrada será:

  • Primeira linha: a capacidade (inteiro)
  • Segunda linha: o número de mensagens a adicionar (inteiro)
  • Linhas seguintes: uma mensagem por linha

Lembre-se: cada new precisa de um delete correspondente, e cada new[] precisa de um delete[] correspondente. Após deletar, é uma boa prática definir os ponteiros como nullptr.

Inclua seu arquivo de cabeçalho no main.cpp usando #include "MessageBox.h".

Folha de consulta

Use new para alocar memória dinamicamente no heap e obter um ponteiro para ela:

int* num = new int;        // Allocate single integer
*num = 42;                 // Assign value through pointer

Player* player = new Player("Hero");  // Allocate object

Todo new deve ter um delete correspondente para liberar a memória:

delete num;      // Free single object
delete player;   // Calls destructor, then frees memory

Para arrays, use new[] e delete[]:

int* scores = new int[5];    // Allocate array of 5 integers
scores[0] = 100;

delete[] scores;             // Free array - note the brackets!

Erros comuns a evitar:

// Memory leak - forgot to delete
int* ptr = new int(10);
ptr = new int(20);    // Lost access to first allocation!

// Dangling pointer - using after delete
delete ptr;
*ptr = 5;             // Undefined behavior!

// Mismatched delete
int* arr = new int[10];
delete arr;           // Wrong! Should be delete[]

Após deletar, defina os ponteiros como nullptr para evitar o reuso acidental.

Experimente você mesmo

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // Lê a capacidade e o número de mensagens
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // Limpa a nova linha após o número
    
    // TODO: Criar um MessageBox no heap usando new
    
    // TODO: Ler e adicionar todas as mensagens ao MessageBox
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // Adiciona a mensagem ao MessageBox
    }
    
    // TODO: Chamar printAll() para exibir todas as mensagens
    
    // TODO: Deletar o MessageBox para liberar memória
    // Lembre-se de definir o ponteiro como nullptr após deletar
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos