Академический Документы
Профессиональный Документы
Культура Документы
de memória
< Programar em C++
Ir para: navegação, pesquisa
Esta página precisa ser reciclada (discuta).
Ao melhorá-la, você estará ajudando o Wikilivros.
Índice
1 Alocação dinâmica de memória
2 Operador new
3 Operador Delete - Memory Leak
4 Retornando um ponteiro para uma variável local
5 Retornando um Ponteiro a uma Variável Local Estática
6 Returning a Pointer to a Dynamically Created Variable
7 Alocar dinamicamente Arrays
8 Dangling Pointers
9 Verificar a existência de memória para dinâmica
Vamos voltar a uma ponta solta num dos capítulos anteriores, onde queríamos fazer
com que o utilizador dissesse quantos elementos do array é que se deveria utilizar. Já
dissemos antes que o declarador do nº de elementos do array tem de ser ou uma
constante ou um literal, mas não pode ser uma variável. Isso dá erro. Aqui vai o
exemplo desse erro:
#include <iostream>
using namespace std;
int main ()
{
int numTests;
cout << "Enter the number of test scores:";
cin >> numTests;
int testScore[numTests];
system ("pause");
return 0;
}
A razão da exigência de ter um constant (ou literal) é que vamos alocar memória para o
array na altura da compilação, e o compilador necessita de saber exactamente a
quantidade de memória que deve reservar… porém se a variável é o size declarator, o
compilador não sabe quanta memória deve reservar para alocar a variável, pois o seu
valor pode mudar.
Operador new
Reformulando o exemplo anterior agora com dados dinâmicos.
#include <iostream>
using namespace std;
int main ()
{
int numTests;
cout << "Enter the number of test scores:";
cin >> numTests;
int * iPtr = new int[numTests]; //colocamos um ponteiro
no inicio da memória dinâmica
for (int i = 0; i < numTests; i++)
{
cout << "Enter test score #" << i + 1 << " : ";
cin >> iPtr[i];
}
for (int i = 0; i < numTests; i++)
cout << "Test score #" << i + 1 << " is "<< iPtr[i] << endl;
delete [] iPtr;
system ("pause");
return 0;
}
O operador new retorna o endereço onde começa o bloco de memória. e como retorna
um endereço vamos colocá-lo num pointer.
Necessitamos do uso do pointer que deverá ser do mesmo tipo que a tipologia de
variável que é alocada dinamicamente. int * iPtr = new int[numTests];
Temos termo NEW. Que é um operador cuja função é alocar dinamicamente
memória
Temos a tipologia da variável a alocar dinamicamente
Repare que NÃO temos o nome do array
Uma vez que o array fica sem nome para nos referirmos a cada elemento do
array teremos de usar o pointer.
ou
Portanto, se realmente não necessitamos mais dos dados que estão nessa memória
dinâmica, em vez de eles estarem a ocupar espaço vamos apagá-los! Necessitamos de
libertar essa memória através do operador delete – este operador entrega ao sistema
operativo a memoria reservada dinamicamente.
A sintaxe é
delete [] iPtr;
Este delete operator não apaga o pointer mas sim a memória onde o ponteiro aponta
void myfunction()
{
int *pt;
int av;
pt = new int(1024);
....
....
//No delete
}
int main()
{
while (some condition exists) // Pseudo-code
{
myfunction();
}
exit 0;
}
O que se passou aqui é que o ponteiro que sai da função setName aponta para o array
local cuja vida acaba quando a função termina de executar. A solução é estender o
tempo de vida. Uma solução era tornar esse array global, mas existem alternativas
melhores.
Retornando um Ponteiro a uma Variável Local
Estática
Uma dessas alternativas é
#include <iostream>
using namespace std;
char * setName();
int main (void)
{
char* str = setName();
cout << str;
system (“pause”);
return 0;
}
char* setName (void)
{
static char name[80]; //crio como static
cout << "Enter your name: ";
cin.getline (name, 80);
return name;
}
A diferença é que usamos a palavra static. O ponteiro do setName aponta para o array
local, e como foi utilizado o static, ele perdura até fim da função, terminando apenas
quando o programa acaba.
#include <iostream>
using namespace std;
char * setName();
int main (void)
{
char* str= setName();
cout << str;
delete [] str; //faço o delete para evitar o memory leak
system ("pause");
return 0;
}
char* setName (void)
{
char* name = new char[80]; //crio ponteiro chamado de name e dou
o valor do endereço da memoria dinâmica
cout << "Enter your name: ";
cin.getline (name, 80);
return name;
}
Isto funciona porque o ponteiro retornado da função setname aponta para o array cujo
tempo de vida persiste. O address do ponteiro local é atribuído no main a outro ponteiro
no main –str. Depois este ponteiro é usado até ao fim da execução do programa. Este é
um exemplo onde diferentes ponteiros apontam para o mesmo endereço.
Mas ter atenção que se fizermos o delete através de um ponteiro, ter cuidado com o
segundo ponteiro que aponta para a memoria que acabou de ser deslocada.
Notar a diferença:
delete[] pt;
delete[] myBills;
Dangling Pointers
int *myPointer;
myPointer = new int(10);
cout << "The value of myPointer is " << *myPointer << endl;
delete myPointer;
*myPointer = 5;
cout << "The value of myPointer is " << *myPointer << endl;
neste exemplo libertámos a memória dinâmica, mas o ponteiro continua isto é um bug
tremendo, e muito dificil de detectar. o programa continua a correr e a secção de
memória pode ser usada por outro objecto dinâmico. acontece que essa memoria estará
corrompida se continuar a usar o myPointer. a melhor maneira é depois do delete fazer
apontar para zero, fazê-lo um ponteiro nulo. se tentarem usar o ponteiro iremos ter a run
time exception e o bug pode ser identificado
int *myPointer;
myPointer = new int(10);
cout << "The value of myPointer is " << *myPointer << endl;
delete myPointer;
myPointer = 0;
*myPointer = 5; //This statement will cause an run-time exception,
now.
cout << "The value of myPointer is " << *myPointer << endl;
vamos ver este caso quase no ultimo capitulo- isto é uma capítulo avançado
// rememb-o-matic
#include <iostream>
using namespace std;
int main ()
{
int i,n,* p;
cout << "How many numbers would you like to type? ";
cin >> i;
p= new (nothrow) int[i]; //criámos I variaveis na
execução
if (p == 0)
cout << "Error: memory could not be allocated";
else
{
for (n=0; n<i; n++)
{
cout << "Enter number: ";
cin >> p[n];
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
}
system ("pause");
return 0;
}