Alocação dinâmica em C

brunosiol 1,059 views 22 slides Oct 07, 2017
Slide 1
Slide 1 of 22
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22

About This Presentation

Apresentação na matéria de linguagem de programação, em 2010, no curso de Análise e Desenvolvimento de Sistemas da Unicamp


Slide Content

Bruno Luis Silveira Andretta
Bruno Silva de Oliveira
Fábio Junco Amaral
Hector Ferreira da Silva
Alocação de Memória

Alocação Estática x Dinâmica
• A linguagem de programação C/C++ permite dois tipos de
alocação de memória: Estática e Dinâmica
- Na alocação estática, o espaço de memória para as variáveis é
reservado ainda na compilação, não podendo ser alterado
depois:
int a;
int b[20];
- Na alocação dinâmica, o espaço de memória para as variáveis
pode ser alocado dinamicamente durante a execução do programa.

Uso da Memória
•Uso de variáveis globais (e estáticas):
–espaço reservado para uma variável global existe enquanto o
programa estiver sendo executado
•Uso de variáveis locais:
–espaço existe apenas enquanto a função que declarou a
variável está sendo executada, liberado para outros usos
quando a execução da função termina
•Variáveis globais ou locais podem ser simples ou vetores:
–para vetor, é necessário informar o número máximo de
elementos pois o compilador precisa calcular o espaço a
ser reservado

Alocação Dinâmica

Alocação Dinâmica
•Espaço de memória é requisitado em tempo de execução
•Espaço permanece reservado até que seja explicitamente
liberado
–depois de liberado, espaço estará disponibilizado para outros
usos e não pode mais ser acessado
–espaço alocado e não liberado explicitamente, será
automaticamente liberado quando ao final da execução

Alocação Dinâmica

Usamos alocação dinâmica quando não sabemos, no momento da
programação, a quantidade de dados que deverão ser inseridos.
É tentar responder a perguntas: quantas pessoas existem em sua turma?
Quantas letras vamos escrever, etc. Em vez de estarmos a prever um limite
superior para abarcar todas as situações, temos esta possibilidade do
dinâmico.
Além de que colocar no momento da programação cria reserva de memória por
isso, estaríamos a reservar memória para um limite que possivelmente não
iríamos ter necessidade. O exemplo típico disto é os processadores de texto.
em que não sabemos a quantidade de letras que o utilizador vai escrever.
Alocação Dinâmica

Alocação Dinâmica em C

•Funções principais (definidas na biblioteca “stdlib.h”)
–Função sizeof(...):
•retorna o número de bytes ocupado por um tipo
–Função malloc(...):
•recebe como parâmetro o número de bytes que se
deseja alocar
•retorna um ponteiro genérico para o endereço inicial
da área de memória alocada, se houver espaço livre.
Alocação Dinâmica em C

• Por exemplo:
–Alocação dinâmica de um vetor de inteiros com 10 elementos
–malloc retorna o endereço da área alocada para armazenar
valores inteiros
–ponteiro de inteiro recebe endereço inicial do espaço alocado
int *v;
v = (int *) malloc(10*sizeof(int));
Alocação Dinâmica em C

–v armazena endereço inicial de uma área contínua de
memória suficiente para armazenar 10 valores inteiros
–v pode ser tratado como um vetor declarado
estaticamente
• v aponta para o inicio da área alocada
• v[0] acessa o espaço para o primeiro elemento
• v[1] acessa o segundo
• .... até v[9]
Alocação Dinâmica em C

–tratamento de erro após chamada a malloc
• imprime mensagem de erro
• aborta o programa (com a função exit)

v = (int*) malloc(10*sizeof(int));
if (v==NULL)
{
printf("Memoria insuficiente.\n");
exit(1); /* aborta o programa e retorna 1 para o
sist. operacional */
}

Alocação Dinâmica em C

•Função free (...):
–recebe como parâmetro o ponteiro da memória a ser liberada
•a função free deve receber um endereço de memória que
tenha sido alocado dinamicamente
free (v);
Alocação Dinâmica em C

Alocação Dinâmica em C++

Alocação Dinâmica em C++
//Alocação Estática
#include <iostream>
int main ()
{
int numTests;
cout << "Entre com o número de teste:";
cin >> numTests;
int testScore[numTests];
system ("pause");
return 0;
}
//Alocação Dinâmica
#include <iostream>
int main ()
{
int numTests;
cout << "Entre com o número de teste:";
cin >> numTests;
int *testScore = new int [numTests];
system ("pause");
delete testScores;
return 0;
}

Operador New

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 ponteiro.

É um operador cuja função é alocar memória dinamicamente.


Podemos inicializar de duas maneiras:
int *valor = new int; ou int *valor = new int(5);
*valor = 5; char *letra = new char('J');

Podemos criar vetores da seguinte maneira:
int *vetor = new int[10];
char *palavra = new char[40];

Operador Delete / Memory Leak
O tempo de vida de uma variável criada dinamicamente é o tempo de execução
do programa.
Se um ponteiro aponta para uma variável dinâmica e fica fora do escopo, já não
conseguiremos ter acesso a essa memória criada dinamicamente.
A isso chama-se Memory Leak.
Explicando:
Se alocamos memória dinamicamente dentro de uma função usando um
ponteiro local, quando a função termina, o ponteiro será destruído, mas a
memória mantém-se.
Assim já não teríamos formas de chamar essa memória porque ela não
tem nome. Apenas tínhamos o endereço que estava no ponteiro.
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 ponteiro;
delete [] vetor;
Este delete não apaga o pointer mas sim a memória onde o ponteiro aponta
Operador Delete

A alocação dinâmica funciona porque a memória não é reservada no momento
da compilação, mas antes na execução.
Em vez de ser no STACK (compilação) a memória é reservada no HEAP
(execução).
O heap é uma parte da memória que é usada como memória temporária.
Heap

void myfunction()
{
int *pt = new int(1024);
int local;
....
//Sem delete
}
int main()
{
while (condição)
{
myfunction();
}
return 1;
}
Heap
Quando a função “myfunction” é chamada a variável “local” é
criada no stack e quando a função acaba a variável é retirada
do stack.
O mesmo acontece com o ponteiro “pt”, ele é uma variável
local, ou seja, quando a função acaba, o ponteiro também
termina e é retirado do stack.
Porém a memória alocada dinamicamente ainda existe. E
agora não conseguimos apagar essa memória porque ela não
tem nome e a única maneira que tínhamos para saber onde ela
estava era através do ponteiro que terminou.
Então a medida que o programa continua a operar, mais e mais
memória será perdida do heap (memória livre).
Se o programa continuar o tempo suficiente, deixaremos de ter
memória disponível e o programa deixará de operar.

Na alocação dinâmica temos de nos certificar de que a alocação no heap foi
feita com sucesso e podemos ver isso de duas maneiras:

Uma é as excepções (este é o método default)
int *bobby = new int [5];
//se falhar, é tratado como “bad_alloc” exception

nothrow, aqui no caso de não se conseguir a memória retorna um ponteiro
nulo, e o programa continua.
int *bobby = new (nothrow) int [5];
//se falhar, o ponteiro recebe NULL
Verificar a existência de memória

Schildt, H. C++ Programming Cookbook.
http://www.dainf.ct.utfpr.edu.br/~karla/
Referências