You are on page 1of 14

Algoritmos e Estrutura de Dados II

DCC - UFMG

Alocao Dinmica de
Memria

int a; int b[20];

Na alocao dinmica, o espao de memria para


as variveis pode ser alocado dinamicamente
durante a execuo do programa

Na alocao esttica, o espao de memria para as


variveis reservado no incio da execuo, no
podendo ser alterado depois

Linguagens de programao como Pascal, C e C++


permitem dois tipos de alocao de memria:
Esttica e Dinmica

Algoritmos e Estrutura de Dados II

Alocao Esttica x Dinmica

Basicamente, o programa aloca e desaloca


pores de memria do heap durante a execuo

A memria alocada dinamicamente faz parte


de uma rea de memria chamada heap

A memria alocada dinamicamente


acessada atravs de Apontadores (pointers)
que na verdade so variveis que armazenam
o endereo de uma rea de memria

Algoritmos e Estrutura de Dados II

Alocao Dinmica

10

Algoritmos e Estrutura de Dados II

a um int
b um apontador para um int

0x020 b 0x234

0x016 a

Memria Esttica

Alocao Dinmica

10

Heap

0x246

0x242

0x238

0x234

0x230

0x226

0x222

0x218

0x214

T *p;

p = (T*) malloc(sizeof(T));

free(p);

*p;

null;

&a;

Endereo de uma varivel a

Valor nulo para um apontador

Conteudo da varivel apontada por P

Desalocao de memria

Alocao de memria para uma varivel apontada por p

definio de p como um apontador para uma varivel do tipo T

Algoritmos e Estrutura de Dados II

Apontadores Notao em C

Algoritmos e Estrutura de Dados II

int *a,*c, b;
...
b = 10;
a = (int *) malloc(sizeof(int));
c = a;
*a = 20;
free(a)
a = &b;
*a = 30; // qual o valor de b?

Alocao Dinmica

Memria no foi
desalocada. O
espao continua
ocupado

b 10
30

Memria
Esttica

20

Heap

Ela desalocada ao fim do programa ou


procedimento funo onde a varivel est
declarada, mas pode ser um problema em loops

Tentar acessar o contedo da varivel depois


de desaloc-la

Esquecer de alocar memria e tentar


acessar o contedo da varivel
Copiar o valor do apontador ao invs do valor
da varivel apontada
Esquecer de desalocar memria

Algoritmos e Estrutura de Dados II

Erros Comuns

Algoritmos e Estrutura de Dados II

a = 3.14;
printf("%f\n", a);
p = &a;
*p = 2.718;
printf("%f\n", a);
a = 5;
printf("%f\n", *p);
p = NULL;
p = (double *)malloc(sizeof(double));
*p = 20;
q = p;
printf("%f\n", *p);
printf("%f\n", a);
free(p);
printf("%f\n", *q);

double a;
double *p, *q;

Exerccio: O que vai ser impresso?

Algoritmos e Estrutura de Dados II

100
100

42657
100

Obs. No se pode fazer a = b


no exemplo acima

int a[10], *b;


b = (int *) malloc(10*sizeof(int));
b[5] = 100;
printf(%d\n, a[5]);
Printf(%d\n, b[5]);

Em C, todo vetor um apontador.


Portanto pode-se fazer coisas como:

int a[10], *b;


b = a;
b[5] = 100;
Printf(%d\n, a[5]);
Printf(%d\n, b[5]);

int *a no a declarao de um vetor de int?

Pergunta que no quer calar...

Apontadores so normalmente utilizados


com tipos estruturados

Algoritmos e Estrutura de Dados II

TRegistro *a;
...
a = (TRegistro *) malloc(sizeof(TRegistro))
a->idade = 30;
a->salario = 80;

Typedef struct {
int idade;
double salario;
} TRegistro

Apontadores para Tipos Estruturados

As modificaes efetuadas acontecem no parmetro real

Por referncia: o parmetro formal (recebido no


procedimento) uma referncia para o parmetro real
(passado na chamada)

Por valor: o parmetro formal (recebido no procedimento)


uma cpia do parmetro real (passado na chamada)

Em C s existe passagem por valor, logo deve-se


implementar a passagem por referncia utilizandose apontadores

Em pascal e C++, parmetros para funo podem


ser passados por valor ou por referncia

Algoritmos e Estrutura de Dados II

Passagem de Parmetros

Algoritmos e Estrutura de Dados II

int main()
{
int a=0, b=0;
int *c;
c = &b;
SomaUm(a, c);
printf("Programa principal: %d %d\n", a,
0 1b);
}

void SomaUm(int x, int *y)


{
x = x + 1;
*y = (*y) + 1;
printf("Funcao SomaUm: %d %d\n", x, *y);
}

Passagem de Parmetros (C)

Algoritmos e Estrutura de Dados II

void aloca(int **x, int n)


{
*x=(int *)malloc(n*sizeof(int));
if (*x == NULL)
printf(ERROR!!!!\n);
else
*x[0] = 20;
OK
}
int main()
{
int *a, **b;
b = &a;
aloca(b, 10);
a[1] = 40;
}

Em C tambm, mas como no h passagem por referncia


as coisas so um pouco mais complicadas

Em pascal, basta passar a varivel (apontador) como


referncia.

E para alocar memria dentro de um procedimento?

void aloca(int *x, int n)


{
x=(int *)malloc(n*sizeof(int));
x[0] = 20;
}
int main()
Error!
{
Access Violation!
int *a;
aloca(a, 10);
a[1] = 40;
}

Passagem de Parmetros

Algoritmos e Estrutura de Dados II

2. Declare um TipoRegistro, com campos a


inteiro e b que um apontador para char.
No seu programa crie dinamicamente uma
vriavel do TipoRegistro e atribua os
valores 10 e x aos seus campos.

1. Faa um programa que leia um valor n, crie


dinamicamente um vetor de n elementos e
passe esse vetor para uma funo que vai
ler os elementos desse vetor.

Exerccios

You might also like