alocdinamica_Aula

March 19, 2018 | Author: Felipe Monteiro Lima | Category: Pointer (Computer Programming), C (Programming Language), Data Type, Computer Data Storage, Computer Program


Comments



Description

Universidade do AmazonasDepartamento de Ciência da Computação Especialização em Desenvolvimento de Sistemas Estruturas de Dados e Algoritmos Alocação Dinâmica de Memória Rosiane de Freitas Rodrigues, Profa. M.Sc. [email protected] http://www.dcc.fua.br/~rosiane setembro de 2001 Manaus - AM Alocação de Memória PROBLEMA O que fazer quando o número de elementos e sua forma de organização variam dinamicamente? Para resolver este problema é necessário um mecanismo que permita:  Criar espaço para novas variáveis em tempo de execução;  Definir ³ligações´ entre tais variáveis, dinamicamente, de tal forma a relacioná-las. Alocação de Memória ± Num vetor, tanto o número como a forma de organização são fixos. ± Em Pascal ou C, o tipo file define uma estrutura que possui um número indeterminado de elementos, porém sempre organizados em seqüência na memória. Alocação de Memória SOLUÇÃO Utilização de ALOCAÇÃO DINÂMICA DE MEMÓRIA, o que significa definir e manipular variáveis especiais denominadas PONTEIROS ou APONTADORES. Alocação de Memória PONTEIRO é ... ± uma variável especial que contém o endereço de memória de outra variável (variável dinâmica); ± variável que contém endereços de posições de memória alocadas na memória. VARIÁVEL PONTEIRO endereço de memória da variável dinâmica VARIÁVEL DINÂMICA conteúdo do tipo T que se deseja ³acessar´ Alocação de Memória VARIÁVEL PONTEIRO endereço de memória da variável dinâmica VARIÁVEL DINÂMICA conteúdo do tipo T que se deseja ³acessar´ ptr <sem nome> 1237 1237 5 . apesar de conter um endereço de memória qualquer (o qual é um inteiro). a variável ponteiro. o acesso ao conteúdo de uma variável dinâmica é obtido através de ponteiros.   .pode ter um ponteiro para qualquer tipo de variável.Alocação de Memória  as variáveis dinâmicas não podem ser referenciadas diretamente. por isto não possuem nome próprio. . deve ser declarado como sendo do mesmo tipo de dado que está contido na variável dinâmica. Os ponteiros podem substituir matrizes estáticas com mais eficiência. Também fornecem a maneira pelas quais procedimentos e funções possam modificar os argumentos chamados.Alocação de Memória uma implementação ligada (por contigüidade lógica ou por alocação dinâmica) utiliza apontadores (do inglês pointers).   . ENDEREÇOS DOS MANIPULADORES DE EXCEÇÃO NÍVEL 4 NÍVEL 3 NÍVEL 2 NÍVEL 1 0000 .O.Alocação de Memória Exemplo de Alocação de Memória em um Computador Pessoal TOPO MEMÓRIA LIVRE PROGRAMAS DO USUÁRIO ENDEREÇO DE MEMÓRIA NÍVEL 6 NÍVEL 5 LP¶s TSR¶s UTILITÁRIOS RESIDENTES DO S. . (Sistema Operacional).reservado para os programas do tipo TSR (Terminate and Stay Residente .Termine e Permaneça Residente). NÍVEL 2 . acesso às portas seriais/paralelas NÍVEL 6 . somente de leitura. que é reservada pelo computador sempre que é ligado. NÍVEL 5 .reservado para ser utilizado pelos programas de usuários. Ex: acesso à placa controladora de vídeo. NÍVEL 4 .reservado para as instruções de máquinas das L.s (Linguagens de Programação).reservado para os manipuladores de interrupção (é utilizado para responder a eventos inesperados que ocorrem durante o processamento).O.reservado para o S.Alocação de Memória Exemplo de Alocação de Memória em um Computador Pessoal NÍVEL 1 .P. Ex: o processo do mouse.memória livre. NÍVEL 3 . Parte desta memória é usada para o acesso aos dispositivos de E/S. Alocação de Memória Exemplo de Alocação de Memória em um Computador Pessoal ± O SISTEMA OPERACIONAL sabe onde inicia e termina cada um dos níveis. NÍVEL 5 NÍVEL 6 - área de pilha (stack) área de heap . que é o de memória livre p/ leitura (principalmente para o acesso aos dipositivos de E/S). ± O NÍVEL 6.P. é utilizado por algumas L.s para a alocação de variáveis dinâmicas.  . desfeitas. porções de memória.Alocação de Memória Alocação Estática A maioria das linguagens de programação atuais faz uso de variáveis para alocar de forma simplificada. endereços. declaração variável <nome. ou seja. e mantém essa relação enquanto o bloco onde foram declaradas estiver ativo. as posições são liberadas e as associações ocorridas. Ao término do mesmo.  Todas as variáveis listadas na cláusula VAR ou no cabeçalho de procedimentos/funções.endereço> var variavel : INTEGER.tipo. são associadas a posições de memória. onde foram alocadas as variáveis daquele escopo.  Cada execução do ambiente cria na stack uma subdivisão. . chamada REGISTRO DE ATIVAÇÃO.Alocação de Memória Alocação Estática  Tais alocações são feitas numa região da memória chamada ÁREA DE PILHA (STACK). PROCEDURE B (). B().Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal.. VAR Princ1. ProcA2. . Princ2 PROCEDURE A (). VAR ProcB1. VAR ProcA1. 1 (Registro de Ativação 1) Princ1. ProcB2.. R.A. FIM. Princ2 STACK (área de pilha) . INICIO A(). Princ2. . B(). ProcB2. VAR Princ1. Princ2 PROCEDURE A (). ProcA2. R.. FIM. 1 (Registro de Ativação 1) Princ1. Princ2. Princ2 STACK (área de pilha) .A..Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. INICIO A(). PROCEDURE B (). VAR ProcB1. VAR ProcA1. INICIO A().Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. Princ2 STACK (área de pilha) . ProcA2. B(). R. 2 R.A. VAR ProcB1. VAR Princ1. Princ2 PROCEDURE A ()... Princ2. VAR ProcA1. 1 ProcA1. ProcA2 PROCEDURE B (). ProcA2 Princ1. FIM.A. ProcB2. . Princ2 PROCEDURE A ().. . FIM..A. ProcA2. PROCEDURE B (). B(). Princ2. INICIO A(). Princ2 STACK (área de pilha) . R. VAR Princ1. VAR ProcA1. ProcB2. 1 Princ1.Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. VAR ProcB1. A. B().Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. FIM.. 1 Princ1. R. VAR ProcA1.. Princ2. Princ2 STACK (área de pilha) . Princ2 PROCEDURE A (). VAR Princ1. PROCEDURE B (). . INICIO A(). ProcB2. ProcA2. VAR ProcB1. A. VAR ProcB1. ProcB2 INICIO A().Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. FIM. VAR Princ1. ProcB2. PROCEDURE B (). Princ2 PROCEDURE A (). 1 ProcB1. Princ2. . B().. ProcA2.A. VAR ProcA1. ProcB2 Princ1. R. Princ2 STACK (área de pilha) .. 2 R. PROCEDURE B (). FIM. . VAR ProcA1. VAR Princ1.Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. Princ2 PROCEDURE A (). Princ2. VAR ProcB1. INICIO A(). Princ2 STACK (área de pilha) .. R. B(). 1 Princ1. ProcA2..A. ProcB2. B(). . FIM. INICIO A(). Princ2 PROCEDURE A (). ProcA2.. PROCEDURE B (). Princ2. VAR ProcB1.Alocação de Memória EXEMPLO: Alocação Estática PROGRAMA Principal. ProcB2. VAR ProcA1. VAR Princ1. STACK (área de pilha) .. Por isto ALOCAÇÃO ESTÁTICA . toda variável que será usada num certo ambiente é pré-alocada quando o ambiente é executado e permanece alocada até que a execução do ambiente termine.Alocação de Memória Alocação Estática IMPORTANTE: Neste esquema de alocação. Alocação de Memória Alocação Dinâmica  Consiste na alocação de porções de memória durante a execução do programa. é visível em qualquer ambiente do programa em execução. O heap. ao contrário dos registros de ativação da stack. ela continua a existir após o término da execução de tal bloco. ou seja.   . embora a alocação seja feita durante a ativação de um determinado bloco do programa. A alocação é feita em uma região especial do espaço de endereçamento do programa chamada HEAP. de um ponteiro para a variável.   .Alocação de Memória Alocação Dinâmica Variáveis dinâmicas não têm nome (identificadores) associados a elas. ou seja. A referência a cada uma delas é feita através de seu endereço na área de heap. que não identifica qualquer variável.Alocação de Memória Alocação Dinâmica em Pascal DECLARAÇÃO VAR <nome-do-ponteiro>: ^<Tipo T> O conteúdo do ponteiro pode consistir de: ± um endereço de memória. um valor especial NIL. identificando uma variável do tipo T. . /* Ponteiro para um valor do tipo T*/ ±  O operador de indireção ^ indica o conteúdo de um objeto apontado por um ponteiro. O operador unário & indica o endereço de uma variável. Pode-se ter um ponteiro para qualquer tipo de variável. estruturas e funções.    .Alocação de Memória Alocação Dinâmica em C PONTEIROS EM C  O grande potencial e flexibilidade da Linguagem C é devido ao uso de ponteiros. C usa ponteiros explicitamente em matrizes. O operador de indireção * indica o conteúdo de um objeto apontado por um ponteiro. Alocação de Memória Alocação Dinâmica em C DECLARAÇÃO <Tipo T> *<nome-do-ponteiro> /* Ponteiro para um valor do tipo T*/ O conteúdo do ponteiro pode consistir de: ± um número de endereços. cada qual identificando uma variável do tipo T. mais o valor especial NULL. que não identifica qualquer variável. ± . Alocação de Memória Alocação Dinâmica PROCEDIMENTOS BÁSICOS Dois procedimentos pré-definidos. . em várias linguagens. ficando este indefinido. cujo endereço é dado pelo parâmetro ptr. DESALOCAR (ptr) Desaloca uma variável dinâmica de tipo T. são utilizados para alocar e desalocar variáveis na área de heap: ALOCAR DESALOCAR ALOCAR (ptr) Aloca uma variável dinâmica de tipo T e atribui o seu endereço ao parâmetro ptr. Alocação de Memória Alocação Dinâmica em PASCAL DECLARAÇÃO var pint : ^INTEGER. pint PROCEDIMENTOS BÁSICOS ALOCAR . // Cria a variável dinâmica *pint DESALOCAR .NEW NEW (pint).DISPOSE DISPOSE (pint). pint pint 340 *pint 340 . pint pint^ o valor de pint é o endereço variável dinâmica do tipo T (denota-se por pint^) . símbolo gráfico usado para representar o NIL .ponteiro para ninguém NEW(pint).Alocação de Memória Alocação Dinâmica em PASCAL pint := NIL. pint PROCEDIMENTOS BÁSICOS ALOCAR MALLOC pint pint 340 pint = (int *) malloc (sizeof (int)).Alocação de Memória Alocação Dinâmica em C DECLARAÇÃO int *pint . FREE . // Cria a var dinâmica *pint *pint 340 DESALOCAR free (pint). Alocação de Memória Alocação Dinâmica em C pint := NULL.ponteiro para ninguém pint = (T *) malloc ( sizeof (T) ) pint *pint o valor de pint é o endereço variável dinâmica do tipo T (denota-se por *pint) . símbolo usado para representar o NULL . o procedimento DISPOSE não é necessário. ± Em C e PASCAL. é necessário explicitar a alocação e a desalocação de ponteiros. . » Criar um OBJETO. INTERESSANTE ± Em JAVA. que possui coletor automático de lixo. significa ALOCAR uma porção de MEMÓRIA DINAMICAMENTE.Alocação de Memória CONSIDERAÇÕES SOBRE LIBERAÇÃO DE MEMÓRIA ± Em MODULA-3 e JAVA. a alocação dinâmica de memória é realizada implicitamente pela linguagem. ou seja. tem-se: ptr_x = &x. *ptr_x. */ . guardar o endereço de x. /* a variável ptr_x aponta para x */ Para o acesso ao conteúdo da variável para qual o ponteiro aponta. Para o ponteiro apontar para x. tem-se: y = *ptr_x.Alocação de Memória Alocação Dinâmica em C DECLARAÇÕES Declarando um ponteiro p/ um inteiro e uma variável x inteira: int x. /* o que é a mesma coisa que: y=x. Não se pode atribuir o endereço de um short int para um long int.Alocação de Memória Alocação Dinâmica em C IMPORTANTE: ± Um ponteiro é associado a um tipo determinado. por exemplo. . ± Soma e subtração de ponteiro (deslocamento de posição na memória).Alocação de Memória Alocação Dinâmica em C OPERAÇÕES C/ PONTEIROS ± Atribuição de endereços ao ponteiro. ± Comparação entre ponteiros com os operadores de igualdade e desigualdade. . ± Obtenção de acesso à variável dinâmica referenciada pelo apontador (esta operação é conhecida por derreferenciação). Assuma que a variável x reside na posição de memória 100.Alocação de Memória Alocação Dinâmica em C MANIPULAÇÃO DE PONTEIROS Considere o efeito do seguinte código: int x=1. na posição 1000. int *ptr. x = ptr. . *ptr = 3. ptr = &x. y=2. que y reside na posição 200 e ptr. y = *ptr. 100 x 1 200 y 2 ptr lixo 1000 ptr = &x.Alocação de Memória Alocação Dinâmica em C Então: int x=1. y=2. int *ptr. 100 1 200 1 100 1000 . 100 1 200 2 100 1000 y = *ptr. 100 y 1 200 ptr 100 1000 1 x = ptr. 100 3 200 1 100 1000 . 100 100 200 1 100 1000 *ptr = 3.Alocação de Memória Alocação Dinâmica em C x y = *ptr. Alocação de Memória Alocação Dinâmica em C IMPORTANTE Em alguns compiladores C. ptr lixo ptr 320 40 x 100 320 . ptr = &x. quando um ponteiro é declarado automaticamente é alocado um endereço válido de memória a ele. um bom código deve suportar qquer ambiente e compilador. tal alocação deve ser feita pelo programa: Então: int *ptr. sempre que possível. O correto seria: int *ptr. int x. *ptr = 100. *ptr = 100. Entretanto. Isto gerará um erro. Neste caso. ++ch_ptr adiciona 1 byte para o endereço.++int_ptr ou ++fl_ptr adiciona 2 bytes e 4 bytes para o endereço. . ± A razão para que seja associado um ponteiro para um tipo de dado é para saber com quantos bytes será necessário para o dado ser armazenado. y Uma operação de soma num ponteiro do tipo inteiro ou float . na verdade. respectivamente. Quando se incrementa o ponteiro.que geralmente é um endereço inteiro. se incrementa o ponteiro por um ³bloco de memória´.Alocação de Memória Alocação Dinâmica em C IMPORTANTE ± Um ponteiro para qualquer tipo é um endereço na memória . Desta forma: y Uma operação de soma num ponteiro do tipo char . se incrementa o ponteiro de float com 2.Alocação de Memória Alocação Dinâmica em C IMPORTANTE Considere uma variável float (fl) e um ponteiro para um float (fl_ptr): 1 float (4 bytes) fl flp ++flp flp+2 ± No exemplo acima. quando se incrementa o ponteiro (++flp) ele é deslocado para a posição 4 bytes adiante. assumindo o ponteiro flp para fl. ou seja. 8 bytes. . ± Se. por outro lado. então ele é deslocado 2 posições float. *px. y=10. printf(³y=%d\n´. *py. px=&x. printf(³&y=%d\n´.*py). printf(³py=%d\n´.Alocação de Memória Alocação Dinâmica em C EXEMPLO main() { int x. printf(³*py=%d\n´. } .px). x = 34.&x). y.x).*px). py=px.&y).py). printf(³x=%d\n´. printf(³&x=%d\n´. printf(³*px=%d\n´. printf(³px=%d\n´.y). Por exemplo: /*balanco é um ponteiro para float*/ main() { int x. float **balanco. **q. ± Num ponteiro normal. q=&p. o valor do ponteiro é o valor do endereço da variável que contém o valor desejado. } . que aponta para a variável que contém o valor desejado. *p. x = 10. printf(³%d´. o primeiro ponteiro contém o endereço do segundo.**q). ± Neste caso. p=&x.Alocação de Memória Alocação Dinâmica em C PONTEIRO PARA PONTEIRO ± Um ponteiro para um ponteiro é uma forma de indicação múltipla. *q. p = (int *) malloc (sizeof (int) ). printf (³%d %d\n´. *p. p = (int *) malloc (sizeof (int) ). printf (³%d %d\n´. *q). *q = x. x = 7.Alocação de Memória Verifique os seguintes comandos: int *p. *p. *q). int x. *p = 5. *q). q = p. Alocação Dinâmica em C . printf (³%d %d\n´. *p. *p = 3. SOLUÇÃO ± definir p como NULL após executar free(p). variável dinâmica não pode nem mesmo ter o espaço liberado. free(p). *p = 10. ± neste caso. . ± a primeira cópia de *p é perdida porque seu endereço não foi salvo.Alocação de Memória Alocação Dinâmica em C PROBLEMA COM PONTEIROS p = (int *) malloc (sizeof (int) ). p = (int *) malloc (sizeof (int) ). *p = 5. ± o espaço alocado para variáveis dinâmicas só podem ser acessados através de um ponteiro. a 1a. uma atribuição a *p muda o valor de *q. ± O programador é responsável pelo rastreamento de ³quais ponteiros estão apontando para aonde´ e pelo reconhecimento da ocorrência de tais resultados implícitos.Alocação de Memória Alocação Dinâmica em C PERIGO COM PONTEIROS ± se q e p são ponteiros com o mesmo valor. ± neste caso. . as variáveis dinâmicas *q e *p são idênticas (referem-se ao mesmo objeto). Alocação de Memória Alocação Dinâmica EXERCÍCIO 1 (em C): Somar dois inteiros usando variáveis dinâmicas: . * pint1 : = * pint1 + * pint2.. Tptr *pint1. free (pint1). *pint2).. . *pint2. pint1.Alocação de Memória EXEMPLO 1: Alocação Dinâmica em C Somar dois inteiros usando variáveis dinâmicas (EM C): TYPE Tptr = ^INTEGER. printf (³%d %d\n´. scanf (³%d %d\n´.. *pint2. pint2 = (int *) malloc (sizeof (int) ). pint2). pint1 = (int *) malloc (sizeof (int) ).. . free (pint2). . LISTAS LIGADAS A estrutura de dados mais simples que pode ser obtida ligando elementos com ponteiros é a LISTA: Cada elemento de uma LISTA LIGADA ou ENCADEADA é representado separadamente. Todos os elementos são ligados através do uso de PONTEIROS.   . LISTA LIGADA É uma lista de pares. A lista ligada pode ser percorrida seguindo os endereços dos ponteiros busca linear: Não é possível o acesso direto a cada elemento da lista ligada.  . cada um consistindo de um elemento e um ponteiro. tal que cada ponteiro contém o endereço do próximo par:  Cada par é representado por um REGISTRO.LISTAS LIGADAS PONTEIROS É simplesmente uma variável cujo valor é o endereço de outro elemento. . que é uma referência para ninguém.  Para visitar. devem ser percorridos os 29 elementos anteriores. por exemplo.  Como detectar o final da lista? Usando um endereço especial. o 30o elemento da lista. chamado NIL.LISTAS LIGADAS DESVANTAGENS Existe um ponteiro (espaço de memória adicional) por elemento.
Copyright © 2024 DOKUMEN.SITE Inc.