A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Alocação Dinâmica de Memória e Tipo Abstrato de Dados Cristiano Arbex Valle Vinicius Fernandes dos Santos

Apresentações semelhantes


Apresentação em tema: "Alocação Dinâmica de Memória e Tipo Abstrato de Dados Cristiano Arbex Valle Vinicius Fernandes dos Santos"— Transcrição da apresentação:

1 Alocação Dinâmica de Memória e Tipo Abstrato de Dados Cristiano Arbex Valle arbex@dcc.ufmg.br Vinicius Fernandes dos Santos viniciussantos@dcc.ufmg.br

2 Alocação dinâmica de memória

3 Algoritmos e Estrutura de Dados II Alocação Estática x Dinâmica C: dois tipos de alocação de memória: Estática e Dinâmica Na alocação estática, o espaço para as variáveis é reservado no início da execução, não podendo ser alterado depois  int a;  int b[20]; P: Qual o espaço de memória que deve ser reservado para um editor de texto?

4 Algoritmos e Estrutura de Dados II Alocação Estática x Dinâmica C: dois tipos de alocação de memória: Estática e Dinâmica Na alocação estática, o espaço para as variáveis é reservado no início da execução, não podendo ser alterado depois  int a;  int b[20]; R: Na alocação dinâmica, o espaço para as variáveis pode ser alocado dinamicamente durante a execução do programa

5 Algoritmos e Estrutura de Dados II Alocação Dinâmica As variáveis alocadas dinamicamente são chamadas de Apontadores (pointers) pois na verdade elas armazenam o endereço de memória de uma variável A memória alocada dinamicamente faz parte de uma área de memória chamada heap  Basicamente, o programa aloca e desaloca porções de memória do heap durante a execução

6 Algoritmos e Estrutura de Dados II Esquema de Memória HEAP STACK

7 Algoritmos e Estrutura de Dados II Alocação Dinâmica a Heap Memória Estática 10 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 a é um int b é um apontador para um int b 0x234 15 0x016 0x020

8 Algoritmos e Estrutura de Dados II Liberação de Memória A memória deve ser liberada após o término de seu uso A liberação deve ser feita por quem fez a alocação:  Estática: compilador  Dinâmica: programador

9 Algoritmos e Estrutura de Dados II Apontadores – Notação (c) Definição de p como um apontador para uma variável do tipo Tipo  Tipo *p; Alocação de memória para uma variável apontada por p  p = (Tipo*) malloc(sizeof(Tipo)); Liberação de memória  free(p); Conteudo da variável apontada por P  *p; Valor nulo para um apontador  NULL; Endereço de uma variável a  &a;

10 Algoritmos e Estrutura de Dados II Alocação Dinâmica int *a, b;... b = 10; a = (int *) malloc(sizeof(int)); *a = 20; a = &b; *a = 30; // qual o valor de b? Heap Memória Estática

11 Algoritmos e Estrutura de Dados II Alocação Dinâmica int *a, b;... b = 10; a = (int *) malloc(sizeof(int)); *a = 20; a = &b; *a = 30; // qual o valor de b? a 20 b Heap Memória Estática 10 X 30 Memória não foi desalocada. O espaço continua ocupado

12 Algoritmos e Estrutura de Dados II Erros Comuns Esquecer de alocar memória e tentar acessar o conteúdo da variável Copiar o valor do apontador ao invés do valor da variável apontada Esquecer de desalocar memória  Ela é desalocada ao fim do programa ou procedimento / função onde a variável está declarada, mas pode ser um problema em loops Tentar acessar o conteúdo da variável depois de desalocá-la

13 Algoritmos e Estrutura de Dados II Alocação Dinâmica de Vetores Normalmente, a alocação dinâmica é utilizada para criar vetores em tempo de execução Exemplo: int *p; p = (int *)malloc(10*sizeof(int));  Aloca um vetor de inteiros com 10 posições. A manipulação pode ser feita normalmente: p[i] =...  O apontador p guarda o endereço (aponta) da primeira posição do vetor.

14 Algoritmos e Estrutura de Dados II Vetores e Apontadores Na verdade, em C todo vetor (mesmo alocados de forma estática) é um apontador para sua primeira posição. Pode se trabalhar usando ambas notações:  *p é equivalente a p[0]  p é equivalente a &p[0]  *(p + i) é equivalente a p[i]  considerando v um vetor alocado estaticamente, e p dinamicamente, pode-se fazer p = v, mas não v = p (v é, de certa forma, um “ponteiro constante”) 6 4 p 0 1...

15 Algoritmos e Estrutura de Dados II Exercício Qual a saída dos programas abaixo? int a[10], *b; b = a; b[5] = 100; printf(“%d\n”, a[5]); printf(“%d\n”, b[5]); int a[10], *b; b = (int*)malloc(10*sizeof(int)); b[5] = 100; printf(“%d\n”, a[5]); printf(“%d\n”, b[5]); 100 42657 100

16 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]);

17 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a M2b M3i M4v[0] M5v[1] M6v[2] M7v[3] M8v[4] M9v[5] M10v[6] M11v[7] M12v[8] M13v[9] M14*p

18 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a110 M2b10 M3i M4v[0] M5v[1] M6v[2] M7v[3] M8v[4] M9v[5] M10v[6] M11v[7] M12v[8] M13v[9] M14pM2

19 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a10 M2b10 M3i0 até 9 M4v[0]0 M5v[1]1 M6v[2]2 M7v[3]3 M8v[4]4 M9v[5]5 M10v[6]6 M11v[7]7 M12v[8]8 M13v[9]9 M14pM4

20 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a10 M2b10 M3i0 até 4 M4v[0]0 M5v[1]10 M6v[2]20 M7v[3]30 M8v[4]40 M9v[5]5 M10v[6]6 M11v[7]7 M12v[8]8 M13v[9]9 M14pM4

21 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a10 M2b10 M3i0 até 4 M4v[0]0 M5v[1]10 M6v[2]20 M7v[3]30 M8v[4]40 M9v[5]-5 M10v[6]6 M11v[7]7 M12v[8]8 M13v[9]9 M14pM9

22 Algoritmos e Estrutura de Dados II Exemplo: O que vai ser impresso? int a, b, i, v[10]; int *p; b = 10; p = &b; a = *p + 100; printf("%d\n", a); a = *&b; printf("%d\n", a); for(i=0; i<10; i++) v[i] = i; p = v; for(i=0; i<5; i++) *(p+i) = 10*i; p = p + 5; *p = -5; for(i=0; i<10; i++) printf(“%d”,v[i]); memóriavariávelconteúdo M1a10 M2b10 M3i0 até 4 M4v[0]0 M5v[1]10 M6v[2]20 M7v[3]30 M8v[4]40 M9v[5]-5 M10v[6]6 M11v[7]7 M12v[8]8 M13v[9]9 M14pM9 0 10 20 30 40 -5 6 7 8 9

23 TIPO ABSTRATO DE DADOS

24 Estrutura de Dados Estruturas de Dados Conjunto de dados que representa uma situação real Abstração da realidade Estruturas de Dados e Algoritmos estão intimamente ligados Algoritmos e Estrutura de Dados II

25 Tipos Abstratos de Dados (TADs) Agrupa a estrutura de dados juntamente com as operações que podem ser feitas sobre esses dados O TAD encapsula a estrutura de dados. Os usuários do TAD só tem acesso a algumas operações disponibilizadas sobre esses dados Usuário do TAD x Programador do TAD Usuário só “enxerga” a interface, não a implementação Algoritmos e Estrutura de Dados II

26 Tipos Abstratos de Dados (TADs) Dessa forma, o usuário pode abstrair da implementação específica. Qualquer modificação nessa implementação fica restrita ao TAD A escolha de uma representação específica é fortemente influenciada pelas operações a serem executadas Algoritmos e Estrutura de Dados II

27 Exemplo: Lista de inteiros Operações do TAD Faz Lista Vazia Insere número no começo da lista Remove de uma posição i 20 13 02 30 Implementação por Vetores: void Insere(int x, Lista L) { for(i=0;...) {...} L[0] = x; } 201302 30 Implementação por Listas Encadeadas void Insere(int x, Lista L) { p = CriaNovaCelula(x); L->primeiro = p;... } Programa usuário do TAD: int main() { Lista L; int x = 20; FazListaVazia(L); Insere(x,L);... }

28 Implementação de TADs Em linguagens orientadas por objeto (C++, Java) a implementação é feita através de classes Em linguagens estruturadas (C, pascal) a implementação é feita pela definição de tipos juntamente com a implementação de funções Não vamos ver em AEDS 2 o conceito de orientação por objetos, vamos utilizar os conceitos de C (typedef e structs) Orientação por objetos (classes, etc) vai ser vista em disciplinas posteriores (POO, Prog. Modular) Algoritmos e Estrutura de Dados II

29 TADs em C Para implementar um Tipo Abstrato de Dados em C, usa-se a definição de tipos juntamente com a implementação de funções que agem sobre aquele tipo Como boa regra de programação, evita-se acessar o dado diretamente, fazendo o acesso só através das funções Mas, diferentemente de C++ e Java, não há uma forma de proibir o acesso. Algoritmos e Estrutura de Dados II

30 typedef Exemplo: Em structs: Algoritmos e Estrutura de Dados II typedef unsigned char byte; void soma(byte b1, byte b2); struct { int x; } S; void f(struct S arg1); typedef struct { int x; } S; void f(S arg1);

31 Definição de tipos Para simplificar, tipos complexos podem ser definidos como novos tipos Não exagerar // Utilidade duvidosa: typedef int[10] Vetor; typedef char[48] Nome; typedef struct { char nome[48]; int matricula; char conceito; } Aluno; typedef struct { int dia; int mes; int ano; } data_t;

32 Uma boa técnica de programação é implementar os TADs em arquivos separados do programa principal Para isso geralmente separa-se a declaração e a implementação do TAD em dois arquivos: NomeDoTAD.h : com a declaração NomeDoTAD.cpp : com a implementação O programa ou outros TADs que utilizam o seu TAD devem dar um #include no arquivo.h TADs em C Algoritmos e Estrutura de Dados II

33 Exemplo Implemente um TAD ContaBancaria, com os campos número e saldo onde os clientes podem fazer as seguintes operações: Iniciar uma conta com um número e saldo inicial Depositar um valor Sacar um valor Imprimir o saldo Faça um pequeno programa para testar o seu TAD Algoritmos e Estrutura de Dados II

34 ContaBancaria.h // definição do tipo typedef struct { int numero; double saldo; } ContaBancaria; // cabeçalho das funções void Inicializa (ContaBancaria**, int, double); void Deposito (ContaBancaria*, double); void Saque (ContaBancaria*, double); void Imprime (ContaBancaria); Algoritmos e Estrutura de Dados II

35 ContaBancaria.c #include #include "Contabancaria.h" void Inicializa(ContaBancaria **conta, int num, double saldo) { *conta = (Conta *) malloc (sizeof(Conta)); (*conta)->numero = num; (*conta)->saldo = saldo; } void Deposito (ContaBancaria *conta, double valor) { conta->saldo += valor; } void Saque (ContaBancaria *conta, double valor) { conta->saldo -= valor; } void Imprime (ContaBancaria conta) { printf("Numero: %d\n", conta.numero); printf("Saldo: %f\n", conta.saldo); } Algoritmos e Estrutura de Dados II

36 Main.c #include #include "ContaBancaria.h" int main (void) { ContaBancaria* conta1; Inicializa(&conta1, 918556, 300.00); printf("\nAntes da movimentacao:\n "); Imprime(*conta1); Deposito(conta1, 50.00); Saque(conta1, 70.00); printf("\nDepois da movimentacao:\n "); Imprime(*conta1); return(0); } Algoritmos e Estrutura de Dados II

37 Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 conta1 é um apontador para ContaBancaria 0x016 LIXO

38 Main.c #include #include "ContaBancaria.h" int main (void) { ContaBancaria* conta1; Inicializa(&conta1, 918556, 300.00); printf("\nAntes da movimentacao:\n "); Imprime(*conta1); Deposito(conta1, 50.00); Saque(conta1, 70.00); printf("\nDepois da movimentacao:\n "); Imprime(*conta1); return(0); } Algoritmos e Estrutura de Dados II

39 Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 0x016 LIXO Inicializa(&conta1, 918556, 300.00); 918556 300.00 num saldo conta 0x016

40 ContaBancaria.c #include #include "Contabancaria.h" void Inicializa(ContaBancaria **conta, int num, double saldo) { *conta = (Conta *) malloc (sizeof(Conta)); (*conta)->numero = num; (*conta)->saldo = saldo; } void Deposito (ContaBancaria *conta, double valor) { conta->saldo += valor; } void Saque (ContaBancaria *conta, double valor) { conta->saldo -= valor; } void Imprime (ContaBancaria conta) { printf("Numero: %d\n", conta.numero); printf("Saldo: %f\n", conta.saldo); } Algoritmos e Estrutura de Dados II

41 Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 0x016 LIXO Inicializa(&conta1, 918556, 300.00); 918556 300.00 num saldo conta 0x016

42 Algoritmos e Estrutura de Dados II Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 0x016 LIXO Inicializa(&conta1, 918556, 300.00); 918556 300.00 num saldo conta 0x016

43 ContaBancaria.c #include #include "Contabancaria.h" void Inicializa(ContaBancaria **conta, int num, double saldo) { *conta = (Conta *) malloc (sizeof(Conta)); (*conta)->numero = num; (*conta)->saldo = saldo; } void Deposito (ContaBancaria *conta, double valor) { conta->saldo += valor; } void Saque (ContaBancaria *conta, double valor) { conta->saldo -= valor; } void Imprime (ContaBancaria conta) { printf("Numero: %d\n", conta.numero); printf("Saldo: %f\n", conta.saldo); } Algoritmos e Estrutura de Dados II

44 Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 0x016 0x230 Inicializa(&conta1, 918556, 300.00); 918556 300.00 num saldo conta 0x016

45 ContaBancaria.c #include #include "Contabancaria.h" void Inicializa(ContaBancaria **conta, int num, double saldo) { *conta = (Conta *) malloc (sizeof(Conta)); (*conta)->numero = num; (*conta)->saldo = saldo; } void Deposito (ContaBancaria *conta, double valor) { conta->saldo += valor; } void Saque (ContaBancaria *conta, double valor) { conta->saldo -= valor; } void Imprime (ContaBancaria conta) { printf("Numero: %d\n", conta.numero); printf("Saldo: %f\n", conta.saldo); } Algoritmos e Estrutura de Dados II

46 Alocação Dinâmica conta1 Heap Memória Estática 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 0x016 0x230 Inicializa(&conta1, 918556, 300.00); 918556 300.00 num saldo conta 0x016 918556 300

47 Algoritmos e Estrutura de Dados II Apontadores para Tipos Estruturados Apontadores podem ser utilizados com tipos estruturados. Isso é muito comum na criação de estruturas encadeadas (listas, filas, etc...) typedef struct { int idade; double salario; } TRegistro;... TRegistro *a;... a = (TRegistro *) malloc(sizeof(TRegistro)); a->idade = 30; // equivalente: (*a).idade a->salario = 80;

48 O que vai ser impresso? typedef struct { int idade; double salario; } TRegistro; int main() { int a, *pa; double b, *pb; TRegistro r, *pr; printf("tam a: %d\n", sizeof(a)); printf("tam pa: %d\n", sizeof(pa)); printf("tam b: %d\n", sizeof(b)); printf("tam pb: %d\n", sizeof(pb)); printf("tam r: %d\n", sizeof(r)); printf("tam pr: %d\n", sizeof(pr)); } tam a: 4 tam pa: 4 tam b: 8 tam pb: 4 tam r: 16 tam pr: 4 32 bits tam a: 4 tam pa: 8 tam b: 8 tam pb: 8 tam r: 16 tam pr: 8 64bits

49 Algoritmos e Estrutura de Dados II Exemplo Declare um TipoRegistro, com os campos: a: inteiro b: apontador para char Crie dinamicamente uma váriavel do TipoRegistro e atribua os valores 10 e ‘x’ aos seus campos

50 Algoritmos e Estrutura de Dados II Respostas typedef struct { int a; char *b; } 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)); } É necessário alocar espaço para o registro e para o campo b.

51 Memória Algoritmos e Estrutura de Dados II 01010100101001010100101010111111010101010101010101001010101010011

52 Memória Algoritmos e Estrutura de Dados II 01010100101001010100101010111111010101010101010101001010101010011 00x12


Carregar ppt "Alocação Dinâmica de Memória e Tipo Abstrato de Dados Cristiano Arbex Valle Vinicius Fernandes dos Santos"

Apresentações semelhantes


Anúncios Google