Memória Dinâmica C ++
Um bom entendimento de como a memória dinâmica realmente funciona em C ++ é essencial para se tornar um bom programador de C ++. A memória em seu programa C ++ é dividida em duas partes -
The stack - Todas as variáveis declaradas dentro da função ocuparão memória da pilha.
The heap - Esta é a memória não usada do programa e pode ser usada para alocar a memória dinamicamente quando o programa é executado.
Muitas vezes, você não sabe com antecedência quanta memória precisará para armazenar informações específicas em uma variável definida e o tamanho da memória necessária pode ser determinado em tempo de execução.
Você pode alocar memória em tempo de execução dentro do heap para a variável de um determinado tipo usando um operador especial em C ++ que retorna o endereço do espaço alocado. Este operador é chamadonew operador.
Se você não precisa mais de memória alocada dinamicamente, pode usar delete operador, que desaloca a memória que foi anteriormente alocada pelo novo operador.
novo e excluir operadores
Há a seguinte sintaxe genérica para usar new operador para alocar memória dinamicamente para qualquer tipo de dados.
new data-type;
Aqui, data-typepode ser qualquer tipo de dados embutido, incluindo uma matriz, ou quaisquer tipos de dados definidos pelo usuário, incluindo classe ou estrutura. Vamos começar com os tipos de dados integrados. Por exemplo, podemos definir um ponteiro para digitar double e então solicitar que a memória seja alocada em tempo de execução. Podemos fazer isso usando onew operador com as seguintes declarações -
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
A memória pode não ter sido alocada com sucesso, se o armazenamento gratuito tiver sido usado. Portanto, é uma boa prática verificar se o novo operador está retornando um ponteiro NULL e tomar as medidas adequadas conforme abaixo -
double* pvalue = NULL;
if( !(pvalue = new double )) {
cout << "Error: out of memory." <<endl;
exit(1);
}
o malloc()função de C, ainda existe em C ++, mas é recomendado evitar o uso da função malloc (). A principal vantagem de new sobre malloc () é que new não apenas aloca memória, mas também constrói objetos que são o objetivo principal do C ++.
A qualquer momento, quando você sentir que uma variável que foi alocada dinamicamente não é mais necessária, você pode liberar a memória que ela ocupa no armazenamento gratuito com o operador 'delete' da seguinte forma -
delete pvalue; // Release memory pointed to by pvalue
Vamos colocar os conceitos acima e formar o seguinte exemplo para mostrar como funcionam 'novo' e 'deletar' -
#include <iostream>
using namespace std;
int main () {
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
*pvalue = 29494.99; // Store value at allocated address
cout << "Value of pvalue : " << *pvalue << endl;
delete pvalue; // free up the memory.
return 0;
}
Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -
Value of pvalue : 29495
Alocação de memória dinâmica para matrizes
Considere que você deseja alocar memória para um array de caracteres, ou seja, string de 20 caracteres. Usando a mesma sintaxe que usamos acima, podemos alocar memória dinamicamente como mostrado abaixo.
char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
Para remover a matriz que acabamos de criar, a instrução ficaria assim -
delete [] pvalue; // Delete array pointed to by pvalue
Seguindo a sintaxe genérica semelhante de novo operador, você pode alocar para uma matriz multidimensional da seguinte maneira -
double** pvalue = NULL; // Pointer initialized with null
pvalue = new double [3][4]; // Allocate memory for a 3x4 array
No entanto, a sintaxe para liberar a memória para a matriz multidimensional ainda permanecerá a mesma acima -
delete [] pvalue; // Delete array pointed to by pvalue
Alocação de memória dinâmica para objetos
Os objetos não são diferentes dos tipos de dados simples. Por exemplo, considere o código a seguir, onde vamos usar uma matriz de objetos para esclarecer o conceito -
#include <iostream>
using namespace std;
class Box {
public:
Box() {
cout << "Constructor called!" <<endl;
}
~Box() {
cout << "Destructor called!" <<endl;
}
};
int main() {
Box* myBoxArray = new Box[4];
delete [] myBoxArray; // Delete array
return 0;
}
Se você alocasse um array de quatro objetos Box, o construtor Simple seria chamado quatro vezes e, da mesma forma, ao excluir esses objetos, o destructor também seria chamado o mesmo número de vezes.
Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!