Alocação dinâmica de memória

A alocação dinâmica de memória em C++ permite que possamos reservar espaço na memória durante a execução do programa, ao invés de definir previamente o tamanho das estruturas de dados. Isso é essencial quando não se sabe, em tempo de compilação, quanto espaço será necessário para armazenar dados.

Por que usar alocação dinâmica?

  • Permite criar estruturas de tamanho variável, como arrays cujo tamanho só é conhecido em tempo de execução.
  • Otimiza o uso de memória, alocando apenas o necessário.
  • É fundamental para manipular grandes volumes de dados ou criar objetos que precisam existir além do escopo de uma função.

Operadores new e delete

Em C++, a alocação dinâmica é feita com o operador new, e a liberação da memória com o operador delete.

Alocar memória para um único valor

int *ptr = new int; // Aloca espaço para um inteiro
*ptr = 42;
cout << *ptr << endl; // Imprime 42
delete ptr; // Liberta a memória
  • new int reserva espaço para um inteiro no heap e retorna o endereço.
  • delete ptr liberta a memória alocada.

Alocar memória para arrays

int tamanho;
cout << "Digite o tamanho do array: ";
cin >> tamanho;

int *vetor = new int[tamanho]; // Aloca array de tamanho variável

for (int i = 0; i < tamanho; i++) {
vetor[i] = i * 2;
}

for (int i = 0; i < tamanho; i++) {
cout << vetor[i] << " ";
}
cout << endl;

delete[] vetor; // Liberta o array
  • new int[tamanho] aloca um array dinâmico.
  • delete[] vetor liberta toda a memória do array.

Alocação dinâmica de objetos

Podemos criar objetos dinamicamente:

class Pessoa {
public:
string nome;
Pessoa(string n) : nome(n) {}
};

Pessoa *p = new Pessoa("João");
cout << p->nome << endl;
delete p;
  • O construtor é chamado ao usar new.
  • Use delete para libertar o objeto.

Uso das funções malloc() e realloc()

As funções malloc e realloc podem ser usadas em C++. Elas fazem parte da biblioteca padrão do C (<stdlib.h>) e estão disponíveis em C++ principalmente por questões de compatibilidade.

No entanto, há algumas observações importantes:

  • malloc e realloc alocam e realocam blocos de memória “bruta”, sem chamar construtores ou destruidores de objetos em C++.
  • O uso dessas funções é comum para manipulação de memória em arrays de tipos primitivos (como int, char, etc.), mas não é recomendado para objetos complexos que possuem construtores ou destruidores, pois eles não serão executados automaticamente.
  • Em C++, a abordagem mais idiomática é usar os operadores new e delete para alocação dinâmica de objetos, ou preferencialmente containers como std::vector para arrays dinâmicos.
  • Se usar malloc e realloc em C++, lembre-se de incluir <cstdlib> (ou <stdlib.h>) e converter o ponteiro retornado para o tipo desejado, pois eles retornam void*.


Pode usar malloc e realloc em C++, especialmente para compatibilidade com código C ou para arrays de tipos primitivos, mas para objetos e código moderno C++, prefira new/delete ou containers da STL.

Cuidados importantes

  • Liberte sempre a memória: Use delete ou delete[] para evitar vazamentos de memória (memory leaks).
  • Não aceda a memória já libertada: Isso pode causar comportamentos indefinidos.
  • Prefira smart pointers: No C++ moderno, use std::unique_ptr ou std::shared_ptr para gerir memória automaticamente e evitar erros.

Exemplo prático: matriz dinâmica

int linhas = 3, colunas = 4;
int **matriz = new int*[linhas];
for (int i = 0; i < linhas; i++) {
matriz[i] = new int[colunas];
}

// Preencher a matriz
for (int i = 0; i < linhas; i++)
for (int j = 0; j < colunas; j++)
matriz[i][j] = i + j;

// Libertar a matriz
for (int i = 0; i < linhas; i++)
delete[] matriz[i];
delete[] matriz;

Exemplo prático: array dinâmico com adição e remoção de elementos

#include <iostream>
using namespace std;

int main() {
    int tamanho = 0;
    int* array = nullptr;

    // Adiciona 3 elementos
    for (int i = 0; i < 3; ++i) {
        int* novoArray = new int[tamanho + 1];
        for (int j = 0; j < tamanho; ++j)
            novoArray[j] = array[j];
        novoArray[tamanho] = i * 10; // Exemplo de valor
        delete[] array;
        array = novoArray;
        tamanho++;
    }

    // Remove o elemento do meio
    int pos = 1;
    int* novoArray = new int[tamanho - 1];
    for (int i = 0, j = 0; i < tamanho; ++i) {
        if (i != pos) novoArray[j++] = array[i];
    }
    delete[] array;
    array = novoArray;
    tamanho--;

    // Exibe o array final
    for (int i = 0; i < tamanho; ++i)
        cout << array[i] << " ";
    cout << endl;

    delete[] array;
    return 0;
}