Olá pessoal, tudo certo?!
O post de hoje começa a “separar os meninos dos homens”. Hoje, começo a falar sobre como funciona a alocação dinâmica (em tempo de execução) de memória.
Diferente do que encontramos em linguagens .NET, onde temos um “garbage collector” cuidando da liberação da memória que utilizamos e que não é mais necessária, em C++ fazemos esse controle “na unha”. Se, por um lado, aumentamos a complexidade, por outro, temos mais controle sobre o que está, de fato, acontecendo.
Se está chegando agora, considere ver os outros posts dessa série.
Por que é necessário saber fazer alocação dinâmica?
Quando declaramos variáveis e especificamos seus tipos estamos, de fato, determinando a quantidade de memória que será necessária para a execução do programa. Tudo isso, em tempo de compilação. Entretanto, frequentemente necessitamos decidir a quantidade de memória que precisará ser alocada em run-time, dependendo, por exemplo, dos inputs dos usuários.
Qualquer programa que faça algum tipo de “carga” e processamento de um conjunto de dados de tamanho desconhecido durante a escrita do código precisará alocar memória para armazenamento em tempo de execução.
Em C++, quando “alocamos” memória dinâmicamente, obtemos um “endereço” de memória que mantemos com um ponteiro.
O que é o Heap?
Durante a execução de nossos programas, há uma quantidade de memória disponível. Ou seja, memória no computador que não está sendo utilizada por outros programas. Essa memória “livre” é conhecida como heap.
Como alocar algum espaço no heap?
Em C++, alocamos algum espaço no heap utilizando o operador new. Quando não desejamos mais utilizar essa memória, liberamos utilizando o operador delete. Considere:
#include; using std::cout; using std::endl; void main() { double *pvalue = nullptr; // aloca espaço no heap para um valor double pvalue = new double; *pvalue = 5; cout << "Valor de pvalue : " << pvalue << endl << "Valor de *pvalue: " << *pvalue << endl; // libera o espaço alocado delete pvalue; }
Executando …
Acho que o código é simples de entender.
Obviamente, podemos alocar a memória e atribuir o valor em uma única linha. Observe:
#include; using std::cout; using std::endl; void main() { // aloca espaço no heap para um valor double double *pvalue = new double(5); cout << "Valor de pvalue : " << pvalue << endl << "Valor de *pvalue: " << *pvalue << endl; // libera o espaço alocado delete pvalue; }
Importante: Sempre que memória alocada não for mais necessária deverá ser, obrigatoriamente, liberada com delete.
Se isso não feito, a memória permanecerá alocada até o fim da execução do programa.
Alocando memória dinamicamente para Arrays
No post anterior, mostrei como criar arrays com tamanho fixo (determinado durante a escrita do código). Agora, é hora de ver como fazer isso em tempo de execução. Considere:
void main() { char* pstring = new char[50]; delete [] pstring; }
A primeira linha, aloca um “array” com 50 chars em memória. A segunda, libera a memória alocada. Repare a utilização dos colchetes junto a instrução delete. Isso indica que estamos removendo um array.
Abaixo, segue uma implementação do “crivo de Eratóstenes” que pede ao usuário o “limite máximo”. Observe:
#include; using std::cout; using std::cin; using std::endl; void main() { int n = 0; cout << "Informe limite superior para primos: "; cin >> n; long i; int* pvalues = new int[n]; for (i = 2; i < n; i++) pvalues[i] = 1; for (i = 2; i < n; i++) if (pvalues[i]) for (int j = i; (j * i) < n; j++) pvalues[i * j] = 0; for (i = 2; i < n; i++) if (pvalues[i]) cout << " " << i; cout << endl; delete [] pvalues; }
Resultado:
Bacana!
Era isso!
Posted on 08/10/2011
0