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 intreserva espaço para um inteiro no heap e retorna o endereço.delete ptrliberta 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[] vetorliberta 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
deletepara 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::vectorpara 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 retornamvoid*.
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
deleteoudelete[]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_ptroustd::shared_ptrpara 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;
}
