Вы находитесь на странице: 1из 17

Alocao Dinmica de

Memria
Luiz Chaimowicz, Raquel O. Prates, Gisele L. Pappa
Algoritmos e Estruturas de Dados II
DCC UFMG
Alocao Esttica x Dinmica
C: dois tipos de alocao de memria: Esttica e
Dinmica

Na alocao esttica, o espao para as variveis


reservado no incio da execuo, no podendo ser
alterado depois
int a; int b[20];

Na alocao dinmica, o espao para as variveis


pode ser alocado dinamicamente durante a
execuo do programa
R. O. Prates Algoritmos e Estrutura de Dados II
Alocao Dinmica
As variveis alocadas dinamicamente so
chamadas de Apontadores (pointers) pois
na verdade elas armazenam o endereo de
memria de uma varivel

A memria alocada dinamicamente faz parte


de uma rea de memria chamada heap
Basicamente, o programa aloca e desaloca
pores de memria do heap durante a execuo

R. O. Prates Algoritmos e Estrutura de Dados II


Esquema de Memria

Memria Esttica Heap

0X214
0x016 a 10
0X218

0x020 b 0X234 0X222


0X226
0X230
10 0X234
0X238
a um int (int a) 0X240
b um apontador para um int (int *b)

R. O. Prates Algoritmos e Estrutura de Dados II


E Java?
Em java no existe manipulao explcita de
apontadores.
Todo objeto criado dinamicamente (new) e

as variveis apontam para os objetos


Variveis dos tipos bsicos so alocadas
estaticamente (no necesrio o new)
A desalocao de memria feita
automaticamente (garbage collection)

R. O. Prates Algoritmos e Estrutura de Dados II


Apontadores Notao em c
definio de p como um apontador para uma varivel do tipo Tipo
Tipo *p;
Alocao de memria para uma varivel apontada por p
p = (Tipo*) malloc(sizeof(Tipo));
Liberao de memria
free(p);
Contedo da varivel apontada por P
*p;
Valor nulo para um apontador
null;
Endereo de uma varivel a
&a;

R. O. Prates Algoritmos e Estrutura de Dados II


Alocao Dinmica
Alocao Heap
int *a, b; Esttica
...
b 10
30
b = 10;
a = (int *) malloc(sizeof(int)); a X
*a = 20;
a = &b;
*a = 30
Qual o valor de b?
20

R. O. Prates Algoritmos e Estrutura de Dados II


Erros Comuns
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
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
R. O. Prates Algoritmos e Estrutura de Dados II
Exerccio: C
double a;
double *p;

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;
printf("%f\n", *p);
printf("%f\n", a);
free(p);
printf("%f\n", *p);

R. O. Prates Algoritmos e Estrutura de Dados II


Pergunta que no quer calar...
int *a no a declarao de um vetor de int?

Em C, todo vetor um apontador.


Portanto pode-se fazer coisas como:
int a[10], *b; int a[10], *b;
b = a; b = (int *) malloc(10*sizeof(int));
b[5] = 100; b[5] = 100;
Printf(%d\n, a[5]); printf(%d\n, a[5]);
Printf(%d\n, b[5]); Printf(%d\n, b[5]);

100 42657 Obs. No se pode fazer a = b


100 100 no exemplo acima

R. O. Prates Algoritmos e Estrutura de Dados II


Apontadores para Tipos Estruturados
Apontadores so normalmente utilizados
com tipos estruturados
Typedef struct {
int idade;
double salario;
} TRegistro

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

R. O. Prates Algoritmos e Estrutura de Dados II


Passagem de Parmetros
Em pascal e C++, parmetros para funo podem ser
passados por valor ou por referncia
Por valor: o parmetro formal (recebido no procedimento) uma
cpia do parmetro real (passado na chamada)
Por referncia: o parmetro formal (recebido no procedimento)
uma referncia para o parmetro real (passado na chamada)
As modificaes efetuadas acontecem no parmetro
real
Em C s existe passagem por valor, logo deve-se
implementar a passagem por referncia utilizando-se
apontadores
R. O. Prates Algoritmos e Estrutura de Dados II
Passagem de Parmetros (C)
void SomaUm(int x, int *y)
{
x = x + 1;
*y = (*y) + 1;
printf("Funcao SomaUm: %d %d\n", x, *y);
} 1 1

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

R. O. Prates Algoritmos e Estrutura de Dados II


Passagem de Parmetros
E para alocar memria dentro de um procedimento?
Em pascal, basta passar a varivel (apontador) como
referncia.
Em C tambm, mas como no h passagem por referncia
as coisas so um pouco mais complicadas
void aloca(int *x, int n) void aloca(int **x, int n)
{ {
x=(int *)malloc(n*sizeof(int)); *x=(int *)malloc(n*sizeof(int));
x[0] = 20; *x[0] = 20;
} }
int main() int main()
Error! OK
{ {
Access Violation! int *a;
int *a;
aloca(a, 10); aloca(&a, 10);
a[1] = 40; a[1] = 40;
} }

R. O. Prates Algoritmos e Estrutura de Dados II


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

R. O. Prates Algoritmos e Estrutura de Dados II


Respostas (1)
void LeVetor(int *a, int n){
int i;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
}
int main(int argc, char *argv[]) {
int *v, n, i;
scanf("%d",&n);
v = (int *) malloc(n*sizeof(int));
LeVetor(v,n);
for(i=0; i<n; i++)
printf("%d\n",v[i]);
}

R. O. Prates Algoritmos e Estrutura de Dados II


Respostas (2)
typedef struct { necessrio alocar espao para
o registro e para o campo b.
int a; *(reg->b) representa o contedo
char *b; da varivel apontada por reg->
} TRegistro;
int main(int argc, char *argv[])
{
TRegistro *reg;
reg = (TRegistro *) malloc(sizeof(TRegistro));
reg->a = 10;
reg->b = (char *) malloc(sizeof(char));
*(reg->b) = 'x';
printf("%d %c",reg->a, *(reg->b));
}

R. O. Prates Algoritmos e Estrutura de Dados II

Вам также может понравиться