Você está na página 1de 28

1

Alocao Dinmica de Memria


Prof. Mauricio Scoton

Alocao Dinmica
At o momento, na declarao de um vetor para
Listas, Pilhas e Filas, tnhamos que saber de antemo
o quanto de espao seria necessrio.
Esse pr-dimensionamento era um fator limitante.
Por exemplo, se desenvolvermos um programa para
calcular a mdia e a varincia das notas de uma
prova, teremos de prever o nmero mximo de
alunos.
(PLT pginas 250 a 256).

Alocao Dinmica
Solues?
Dimensionar o vetor com um nmero absurdamente alto,
para no termos limitaes no momento da utilizao do
programa.
Sermos modestos no pr-dimensionamento do vetor.

Alocao Dinmica
Desvantagens?
Desperdcio de memria, o que inaceitvel em diversas
aplicaes.
Programa fica muito limitado, pois no conseguiramos
tratar turmas com um nmero de alunos maior que o
previsto.

Alocao Dinmica
A linguagem C oferece meios de requisitar espaos
de memria em tempo de execuo.
Dizemos
que
podemos
alocar
memria
dinamicamente.

Alocao Dinmica
Uso da memria
Podemos dizer que existem trs maneiras de
reservar espao de memria para o armazenamento
de informaes:
Usar variveis globais
Usar variveis locais
Alocar memria dinamicamente.

Alocao Dinmica
A primeira usar variveis globais (e estticas). O
espao reservado para uma varivel global existe
quanto o programa estiver sendo executado.
A segunda maneira usar variveis locais. Nesse
caso, o espao existe apenas enquanto a funo que
declarou a varivel est sendo executada, sendo
liberado para outros usos quando a execuo da
funo termina.

Alocao Dinmica
A terceira maneira de reservar memria requisitar
ao sistema, em tempo de execuo, um espao de
um terminado tamanho. Esse espao alocado
dinamicamente permanece reservado at que seja
explicitamente liberado pelo programa.
A partir do momento em que liberarmos o espao,
ele estar disponibilizado para outros usos e no
podemos mais acess-lo.

Alocao Dinmica
Se o programa no liberar um espao alocado, ele
ser automaticamente liberado quando a execuo
do programa terminar.
Na figura 1, apresentamos um esquema didtico que
ilustra de maneira fictcia a distribuio do uso da
memria pelo sistema operacional.

Alocao Dinmica
Cdigo do
Programa

Variveis Globais
e Estticas
Memria Alocada
Dinamicamente

Memria Livre

Pilha

O sistema operacional reserva


espaos necessrios para
armazenar as variveis globais
(e estticas) existentes no
programa e o restante da
memria livre utilizado pelas
variveis locais e pelas
variveis
alocadas
dinamicamente.

Alocao Dinmica
Cada vez que uma determinada funo chamada, o
sistema reserva o espao necessrio para as variveis
locais da funo.
Esse espao pertence pilha de execuo e, quando
a funo termina, desempilhado.
A parte da memria no ocupada pela pilha de
execuo pode ser requisitada dinamicamente.

Alocao Dinmica
Funes da biblioteca padro
Existem funes, presentes na biblioteca padro
stdlib, que permitem alocar e liberar memria
dinamicamente.
A funo bsica para alocar memria malloc.
Ela recebe como parmetro o nmero de bytes que
se deseja alocar e retorna o endereo inicial da rea
da memria alocada.

Alocao Dinmica
Para exemplificar, vamos considerar a alocao
dinmica de um vetor de inteiros com 10 elementos.
Como a funo malloc tem como valor de retorno o
endereo da rea alocada e, nesse exemplo,
desejamos armazenar valores inteiros nessa rea,
devemos declarar um ponteiro de inteiro para
receber o endereo inicial do espao alocado.

Alocao Dinmica
O trecho de cdigo ento seria:
int *v;
v = malloc(10*4);

Aps esse comando, se a alocao for bem sucedida,


v armazenar o endereo inicial de uma rea
contnua de memria suficiente para armazenar 10
valores inteiros.

Alocao Dinmica
Podemos, ento, tratar v como tratamos um vetor
declarado estaticamente, pois, se v aponta para o
incio da rea alocada, sabemos que v[0] acessa o
espao o primeiro elemento a ser armazenado, v[1]
acessa o segundo, e assim por diante (at v[9]).

Alocao Dinmica
No exemplo mostrado, consideremos que um inteiro
ocupa 4 bytes. Para ficarmos independentes de
compiladores e mquinas, usamos o operador
sizeof()
v = malloc(10*sizeof(int));

Alm disso, devemos salientar que a funo malloc


usada para alocar espao para armazenar valores de
qualquer tipo.

Alocao Dinmica
Por esse motivo, malloc retorna um ponteiro
genrico, para um tipo qualquer, representado por
void*, que pode ser convertido automaticamente
pela linguagem para o tipo apropriado na atribuio.
No entanto, comum fazer a converso utilizando o
operador de molde de tipo (cast).

Alocao Dinmica
O comando para a alocao do vetor de inteiros fica ento:
v = (int*) malloc (10*sizeof(int));
Assim, o ponteiro v aponta para o endereo inicial de uma
rea contnua de memria para 10 inteiros.
O operador sizeof() obtm o tamanho em bytes do tipo int e
o operador de cast (int*), converte o ponteiro genrico
retornado por malloc para um ponteiro do tipo int*.

Alocao Dinmica
1 Declarao: int *v
Abre-se Espao na pilha para o
ponteiro (varivel local)

2 Comando:
v = (int*)malloc(10*sizeof(int))
Reserva espao de memria da rea
livre e atribui endereo varivel

Cdigo do Programa

Cdigo do Programa

Variveis Globais e
Estticas

Variveis Globais e
Estticas
40 bytes

Livre

Livre

504

Alocao Dinmica
Se, porventura, no houver espao livre suficiente
para realizar a alocao, a funo retorna um
endereo nulo (representado pelo smbolo NULL,
definido em stdlib.h).
Podemos cercar o erro na alocao da memria
verificando o valor de retorno da funo malloc.

Alocao Dinmica
...
v = (int*) malloc (10*sizeof(int));
if (v == NULL)
{
printf(Memoria insuficiente.\n);
exit(1);
}
...

Alocao Dinmica
Para liberar um espao de memria alocado
dinamicamente, usamos a funo free.
Essa funo recebe como parmetro o ponteiro da
memria a ser liberada.
Assim, para liberar o vetor v, fazemos:
free (v);

S podemos passar para a funo free um endereo


de
memria
que
tenha
sido
alocado
dinamicamente.

Alocao Dinmica
- Exemplo
main()
{
int i, n;
float *v;
float med;
printf("Quantas notas sero lidas?: ");
scanf("%i",&n);
/*alocao dinmica*/
v = (float*) malloc (n*sizeof(float));
if(v == NULL) {
printf("Memria Insuficiente");
return 1;
}

/*leitura dos valores*/


for(i=0; i<n; i++){
printf("Entre com a nota %i: ",i);
scanf("%f", &v[i]);
}
med = media(n,v);
printf("Media: %.2f ", med);
getche();
/*libera memria*/
free(v);
return 0;
}

Alocao Dinmica
- Exemplo
/* funo para clculo da mdia */
float media(int n, float *v)
{
int i;
float s = 0.0f;
for(i=0; i<n; i++)
s += v[i];
return s/n;
}

Alocao Dinmica
- Outro Exemplo
main()
{
1
int *p, *q;
2
int x;
3
p = (int*) malloc(sizeof(int));
4
*p = 3;
5
q = p;
6
printf("%d %d\n", *p, *q);
7
x = 7;
8
*q = x;
9
printf("%d %d\n", *p, *q);
10 p = (int*) malloc(sizeof(int));
11 *p = 5;
12 printf("%d %d\n", *p, *q);
}

Na linha 3, uma varivel inteira


criada e seu endereo colocado em
p.
A linha 4 define o valor dessa varivel
como 3.

A linha 5 define q com o valor dessa


varivel. (ver Figura a)
A linha 6, portanto, imprime o
contedo dessa varivel (que 3)
duas vezes.
A linha 7 define o valor de uma
varivel de inteiro, x, com 7

Alocao Dinmica
- Outro Exemplo
main()
{
1
int *p, *q;
2
int x;
3
p = (int*) malloc(sizeof(int));
4
*p = 3;
5
q = p;
6
printf("%d %d\n", *p, *q);
7
x = 7;
8
*q = x;
9
printf("%d %d\n", *p, *q);
10 p = (int*) malloc(sizeof(int));
11 *p = 5;
12 printf("%d %d\n", *p, *q);
}

A linha 8 muda o valor de *q para o


valor de x. Entretanto, como p e q
apontam ambos para a mesma
varivel, *p e *q tm o valor 7. (ver
Figura b)
A linha 9, portanto, imprime o
nmero 7 duas vezes.
A linha 10 cria uma nova varivel
inteira e coloca seu endereo em p.
(ver Figura c)
A linha 11 define o valor dessa
varivel recm-criada com 5 (ver
Figura d)
A linha 12 imprime os valores 5 e 7.

Alocao Dinmica
- Outro Exemplo
p
q

3
a)

p
q

7
b)
q

c)
q

d)

Você também pode gostar