Ponteiros e Alocação Dinâmica

Preview:

Citation preview

slide 1

Estrutura de Dados I

UNICAP

Eduardo Araújo Oliveirahttp://eduoliveira.com

Twitter: @oliveiraeduardo

slide 2

PONTEIROS

slide 3

“Memória?”

slide 4

Uma memória é uma seqüência de células de armazenamento

(ou posições)

slide 5

“Uma variável é um aglomerado de

uma ou mais células de memória”.

slide 6

Atributos de uma variável

– nome: seqüência de caracteres utilizada para identificar avariável;

– tipo: é o tipo dos dados que serão armazenados na variável;

– conteúdo: é o valor armazenado na variável;

– endereço: é a localização (posição) da variável na memória;

Variável

slide 7

slide 8

– char sexo = ‘M’;

• Nome da variável: sexo• Tipo da variável: char• Conteúdo da variável: ‘M’• Endereço da variável: 5

Variável

slide 9

– int idade = 31;

• Nome da variável: idade• Tipo da variável: int• Conteúdo da variável: 31• Endereço da variável: 1

Variável

slide 10

– int idade = 31;

• Nome da variável: idade• Tipo da variável: int• Conteúdo da variável: 31• Endereço da variável: 1

Variável

slide 11

Ponteiros, como o próprio nome diz, é um tipo de variável queaponta para outra (de um tipo qualquer).

• Um ponteiro guarda o endereço de memória de uma variável.• Sintaxe: Variáveis que são ponteiros são representadas daseguinte forma:

tipo_dado_apontado *nome_variavel;

Variáveis do tipo ponteiro

– int *ptr1;– char *ptr2;

slide 12

Utilizado para:

– Substituir a manipulação de vetores/matrizes com eficiência;

– Passar valores e mudar valores dentro de funções;

– Manipular arquivos;

– Aumento de eficiência para algumas rotinas;

– Possibilitar a alocação dinâmica de memória.

Variáveis do tipo ponteiro

slide 13

Operadores de Endereço

– O & (“endereço de”) antes de um nome de variável qualquer

retorna o endereço desta variável.

– O * (“conteúdo de”) antes de um nome de variável do tipo

ponteiro retorna o conteúdo armazenado na posição dememória apontada. Operação chamada de indireção oudesreferenciamento.

Variáveis do tipo ponteiro

slide 14

char letra = ‘Z’;char *ptr = &letra;

– Nome da variável: ptr– Tipo da variável: char *– Conteúdo da variável: 1– Endereço da variável: 4

Variáveis do tipo ponteiro

slide 15

void main(){int x = 50;int * ptr;printf (“%i”,x); /*exibe o conteúdo da variável x (50)*/printf (“%p”,&x); /*exibe o endereço da variável x*/ptr = &x; /*armazena em ptr o endereço de x*/printf (“%p”,ptr); /*exibe o conteúdo da variável ptr*/printf (“%p”,&ptr); /*exibe o endereço da variável ptr*/printf (“%i”,*ptr); /*exibe o conteúdo da variável x*/}

Variáveis do tipo ponteiro

slide 16

void main () {int x;int *ptr;printf(“Digite um valor para x:”);scanf(“%i”, &x);ptr = &x;*ptr = *ptr + 1;printf(“O valor de x é %i”, *ptr);

printf(“O endereço de x é %i”, ptr);}

Variáveis do tipo ponteiro

slide 17

*p ⇒ representa o conteúdo da variável apontada.

p ⇒ representa o endereço de memória da variável apontada.

Variáveis do tipo ponteiro

slide 18

Observação– Quando queremos indicar que um ponteiro está “vazio”, ouseja, não contém um endereço de uma variável, atribuímosa ele o valor NULL.

• NULL: Endereço de memória 0 (zero). Esta posição de

memória não é utilizada para armazenar dados.

– Exemplo:ptr = NULL; /* inicializa o ponteiro ptr*/

Variáveis do tipo ponteiro

slide 19

int a = 5, b = 7; (neste exemplo, um int ocupa 2bytes namemoria, e não 4, como em outros exemplos).int *ptr = NULL;

ptr = &a;

Variáveis do tipo ponteiro

slide 20

Atribuição

– Podemos atribuir o conteúdo de um ponteiro a outro. Dessaforma, teremos dois ponteiros referenciando o mesmo endereçode memória.

• Exemplo:int a = 5, *p1, *p2;p1 = &a;p2 = p1;

Variáveis do tipo ponteiro

slide 21

Sendo os ponteiros números que representam posições dememória, podem ser realizadas algumas operações aritméticassobre eles:

– Incremento;– Decremento;– Diferença;– Comparação.

Aritmética de ponteiros

slide 22

Incremento e Decremento

– Um ponteiro pode ser incrementado como qualquer outravariável

– Se ptr é um ponteiro para um determinado tipo, quando ptr éincrementado, por exemplo, de uma unidade, o endereço quepassa a conter é igual ao endereço anterior de ptr + sizeof(tipo)para que o ponteiro aponta

– A mesma situação ocorre para a operação de decremento,onde o endereço que passa a conter é igual ao endereçoanterior de ptr - sizeof(tipo) para que o ponteiro aponta

Aritmética de ponteiros

slide 23

int main(int argc, char **argv) {int x = 5, *px = &x;double y = 5.0, *py = &y;

printf("%i %i\n", x, px);printf("%i %i\n", x+1, px+1);

printf("%f %i\n", y, py);printf("%f %i\n", y+1, py+1);

printf("%i %i\n", x, px);printf("%i %i\n", x-1, px-1);

printf("%f %i\n", y, py);printf("%f %i\n", y-1, py-1);getchar();return 0;}

Aritmética de ponteiros

5 22935246 22935285.000000 22935126.000000 22935205 22935244 22935205.000000 22935124.000000 2293504

slide 24

Além das operações de incremento e decremento, só é possível

somar ou subtrair inteiros de um ponteiro:

– ptr = ptr + 7;• Esta expressão faz com que ptr aponte para o sétimo elemento a partir do seu elemento atual.

– ptr = ptr – 5;• Esta expressão faz com que ptr aponte para o quinto elemento anterior ao elemento atual.

Aritmética de ponteiros

Somar 2 a um ponteiro de inteiros de 4 bytes irá incrementá-lo em 8. Isso fazcom que o incremento de um ponteiro o posicione para o próximo elemento emum arranjo, o que geralmente é o resultado intencionado.

Aritmética de ponteiros

• Adição: somar um inteiro a um ponteiro

• Exemplo:float *p;p = p + 2;

Fator de escala: é o tamanho (número debytes) do objeto apontado.

• Exemplo: fator de escala de uma variável do tipofloat: 4

p = p + 2 significa p = p + 2 * fator de escala

slide 25

Aritmética de ponteiros

• Subtração: subtrair um inteiro de um ponteiro

• Exemplo:float *p;p = p - 3;

p = p - 3 significa p = p - 3 * fator de escala

slide 26

Aritmética de ponteiros

Aritmética de Ponteiros• Incremento: somar um a um ponteiro

• Exemplo:float *p;p++; OU ++p;

slide 27

Aritmética de ponteiros

Aritmética de Ponteiros• Decremento: subtrair um de um ponteiro

• Exemplo:float *p;p--; OU --p;

slide 28

slide 29

Comparação

– É possível comparar dois ponteiros em uma expressão relacional.

-Exemplo:É possível verificar se um ponteiro aponta para um endereço menor que o endereço apontado por outro ponteiro:

if (px < py)printf(“px aponta para memória mais baixa que py”);

Aritmética de ponteiros

slide 30

Precedência de Operadores

– O operador * e & têm maior precedência que os operadores aritméticos, de forma que:

// obtém o valor do objeto apontador por px, adiciona 1 e //atribui o valor a yy = *px + 1;

// y recebe o conteúdo do endereço de px+1 y = *(px + 1);

Aritmética de ponteiros

slide 31

Precedência de Operadores

– Os operadores ++ e -- possuem precedência sobre o * e operadores matemáticos

(*px)++; //soma 1 no conteúdo de px

*px++; //adianta uma posição de memória e obtém o seu //conteúdo

*(px--); //volta uma posição de memória e obtém //o seu conteúdo ⇒ o mesmo que *px--

Cuidado com ponteiros perdidos!

Expressões com ponteiros

slide 32

Diferença– A operação de diferença entre elementos de mesmo tipo permite saber quantos elementos existem entre um endereço e outro.

– Exemplo:#include <stdio.h>void main(){int x = 5, *px = &x;int y = 10, *py = &y;printf("%i %d\n", x, px);printf("%i %d\n", y, py);printf("\A diferenca entre eles eh: %d", py - px);getchar();}

Aritmética de ponteiros

slide 33

Como os outros tipos do C, as estruturas podem ser referenciadas usando ponteiros.

typedef struct {int numero;char nome[10];float saldo;

} conta;conta conta1;conta *ptr;ptr = &conta1;

Ponteiro para estrutura

slide 34

Há duas formas para recuperar os valores de uma estrutura usando o ponteiro:

– Se st é uma estrutura e ptr é um ponteiro para st, para referenciar a estrutura usamos:

(*ptr).elemento ou ptr->elemento

Ponteiro para estrutura

slide 35

conta conta1, *ptr;conta1.num_conta = 2;strcpy(conta1.nome, “Maria”);conta1.saldo = 482.25;ptr = &conta1;

printf(“Numero = %i\n”, (*ptr).num_conta);printf(“Nome = %s\n”, (*ptr).nome);pritnf(“Saldo = %f\n”, (*ptr).saldo);/* ou */printf(“Numero = %i\n”, ptr->num_conta);printf(“Nome = %s\n”, ptr->nome);pritnf(“Saldo = %f\n”, ptr->saldo);

Ponteiro para estrutura

typedef struct {int num_conta;char nome[10];float saldo;

} conta;

slide 36

typdef struct{char titulo [40];float preco;

} livro ;

void main(){

livro liv, *ptr; gets (liv.titulo);scanf(“%f”, &liv.preco);ptr = &liv;ptr->preco = ptr->preco * 0.1;printf(“O preço de %s eh %f.”, pt->titulo, pt->preco);

}

Ponteiro para estrutura

slide 37

Exercício

– Fazer um programa que permita a entrada de registros com nome, cidade e telefone de 1 pessoa usando a sintaxe de ponteiro para estrutura.

Ponteiro para estrutura

slide 38

O nome de um vetor corresponde ao endereço do seu primeiroelemento, isto é, se v for um vetor então v é igual ao &v[0].

Embora o nome de um vetor seja um ponteiro para o primeiroelemento do vetor, esse ponteiro não pode ser alterado durantea execução do programa a que pertence.

Ponteiro e Vetor

slide 39

Existem duas formas de colocar um ponteiro apontando para oprimeiro elemento de um vetor:

int v[3] = {10, 20, 30};int * ptr;

ptr = &v[0]; // ouptr = v;

Ponteiro e Vetor

slide 40

Ao contrário de v, que é um vetor (ponteiro constante associadoà sua própria memória), ptr é um ponteiro puro, e portantopode receber endereços de diferentes elementos de um vetor.

int v[3] = {10, 20, 30};int *ptr;ptr = v;printf(“%i %i”, v[0], *ptr); /* 10 10 */ptr = &v[2]printf(“%i %i”, v[2], *ptr); /* 30 30 */

Ponteiro e Vetor

slide 41

Outra sintaxe

– Colocamos em c o endereço do terceiro elemento de vetor:char vetor[5] = { ‘a’, ‘e’, ‘i’, ‘o’, ‘u’ };char *c;c = &vetor[2];

– Portanto:c[0] = ‘i’; c[1] = ‘o’ e c[2] = ‘u’.

– Se tivéssemos feito c = &vetor[3], então:c[0] = ‘o’ e c[1] = ‘u’.

Ponteiro e Vetor

slide 42

Usando aritmética de ponteiros, como acessar os valores dovetor usando a variável ponteiro c ?

#include <stdio.h>void main(){int i;char vetor[5] = { 'a', 'e', 'i', 'o', 'u' };char *c;c = vetor;for (i = 0; i < 5; i++) {printf("\n%c ", c[i]); /* ou */printf("%c ", *(c + i));}getchar();}

Ponteiro e Vetor

slide 43

Usando a sintaxe de ponteiro e de vetor de que formapoderemos acessar o caractere ‘a’ presente na string“OlaOleOli”?

#include <stdio.h>#include <stdio.h>void main(){int i;char vetor[] = "OlaOleOli";char *c = vetor;

printf("\n%c ", vetor[2]);printf("%c ", *(c + 2));printf("\n%c ", c[2]);printf("%c ", *(vetor + 2));

getchar();}

Ponteiro e Vetor

slide 44

Resumo– Quando estamos manipulando ponteiros para vetores:

*c ⇒ representa o conteúdo da variável.

*(c + i) ⇒ representa o i-ésimo elemento do vetor referenciadopelo ponteiro.

c[i] ⇒ também representa o i-ésimo elemento do vetorreferenciado pelo ponteiro.

c ⇒ representa o endereço de memória da variável.

Ponteiro e Vetor

slide 45

Exercício:

– Dadas as variáveis float vet_notas[5] e float *pont_notas,imprimir a primeira e a quinta nota usando as duas variáveis.

printf(“A primeira nota: %i”, vet_notas[0]);printf(“A primeira nota: %i”, *pont_notas);printf(“A quinta nota: %i”, vet_notas[4];printf(“A quinta nota: %i”, *(pont_notas+4));

Ponteiro e Vetor

slide 46

Sempre que invocamos uma função e lhe passamos um vetorcomo parâmetro, essa na realidade não recebe o vetor na suatotalidade, mas apenas o endereço inicial do vetor, pois estamospassando v que é igual a &v[0].

Se passarmos um endereço, então a variável que recebe teráque ser um ponteiro para o tipo dos elementos do vetor.

Por essa razão é que no cabeçalho de uma função que recebeum vetor como argumento aparece um ponteiro recebendo orespectivo parâmetro.

Passagem de Vetores para funções

slide 47

#include <stdio.h>void exibirVetor( int * ptr, int tam ){int i;for (i = 0; i < tam; i++) {printf("%i ", *(ptr + i));}}void main(){int vetor[] = {1, 2, 3, 4, 5};

exibirVetor(vetor, 5);getchar();}

Passagem de Vetores para funções

slide 48

Conclusão– Variáveis para vetores podem ser declaradas como sendoapontadores, pois os elementos do vetor, individualmente, têmo mesmo tratamento independente se a variável que osarmazena é um vetor ou um apontador.

char vetor[5] equivale a char *vetor;

– Versões com ponteiros são mais rápidas!

Ponteiro e Vetor

slide 49

Pode-se criar e manipular uma string fazendo uso apenas de umponteiro.

Exemplo:

char *palavra = “exemplo”;for(; *palavra != ‘\0’; palavra++)printf(“%c ”, *palavra);

Ponteiro e String

slide 50

Exercícios:

– Usando ponteiro para string escreva um função que mostre astring recebida por parâmetro na tela pela ordem em que estáescrita e pela ordem contrária.

– Usando ponteiro para string e diferença entre ponteirosescreva uma função que calcule o comprimento de uma stringrecebida por parâmetro. Obs.: Não pode usar a função strlen!

Ponteiro e String

slide 51

Uma vez que os ponteiros ocupam espaço em memória, épossível obter a sua posição através do operador de endereço &

Pergunta: Se quisermos armazenar o endereço de um ponteiro,qual o tipo da variável que irá recebê-lo?

Ponteiro para Ponteiro

slide 52

Resposta:– Suponha uma variável do tipo int chamada x– Se quisermos armazenar seu endereço, declaramos umponteiro para o tipo da variável (int), isto é, colocamos umasterisco entre o tipo da variável para que queremos apontar eo nome do ponteiro

int *ptr_x;

– Se quisermos armazenar o endereço desse ponteiro, seguimosexatamente os mesmos passos

int **ptr_ptr_x;

Ponteiro para Ponteiro

slide 53

Resposta:– Os passos podem ser aplicados sucessivamente para qualquernúmero de asteriscos• int ****ptr = NULL; /* Válido */

– Ponteiro para ponteiro para ponteiro para ponteiro parainteiro!– Para chegar no destino final temos que fazer 4 indireções! Umprograma que use isso é difícil de entender e pode ficar muitolento!

Ponteiro para Ponteiro

slide 54

#include <stdio.h>void main(){int x = 5;int * ptr_x; /* Ponteiro para x */int ** ptr_ptr_x; /* Ponteiro para o ponteiro de x *//* Carga inicial dos ponteiros */ptr_x = &x;ptr_ptr_x = &ptr_x;

printf("x = %i e &x = %i\n", x, &x);printf("x = %i e &x = %i\n", *ptr_x, ptr_x);printf("x = %i e &x = %i\n", **ptr_ptr_x, *ptr_ptr_x);getchar();}

Ponteiro para Ponteiro

slide 55

int x = 5;int * ptr_x;int ** ptr_ptr_x;/* Carga inicial dos ponteiros */ptr_x = &x;ptr_ptr_x = &ptr_x;

Ponteiro para Ponteiro

slide 56

Aplicação– Uma aplicação de ponteiros para ponteiros está nas strings, jáque strings são vetores, que por sua vez são ponteiros.

– Um vetor de strings seria justamente um ponteiro para umponteiro.

Ponteiro para Ponteiro

slide 57

ATENÇÃO– Ponteiro é uma variável que não tem memória própriaassociada, ela apenas contém o espaço para conter umendereço.

– Portanto, só se pode utilizar o endereçamento através doponteiro depois que este está apontando para algum objeto jáexistente.

– Não se deve fazer cargas iniciais de objetos apontadospor um ponteiro ainda não iniciado– Exemplo:int * p;*p = 234;

Ponteiro para Ponteiro

slide 58

O termo void aplicado a um ponteiro significa um ponteiro quepode acessar qualquer tipo de dado

Sintaxe: void * ptr;

Exemplo:void main(){void * ptr;int x = 10;ptr = &x;printf("x = %d e &x = %p", x, &x);printf("\nx = %d e &x = %p", *((int*)ptr), ptr);

getchar();

Ponteiro para Void

slide 59

ALOCAÇÃODINÂMICA

slide 60

Alocação– Processo de vinculação de uma variável de programa a umacélula de memória de um pool de memória disponível

Desalocação– Processo de devolução de uma célula de memóriadesvinculada de uma variável ao pool de memória disponível

Memória

slide 61

Tempo de vida de uma variável é o tempo durante o qualela está vinculada a uma localização de memória específica;

Tempo de vida de uma variável é o intervalo de tempodecorrente entre a sua alocação (criação) e a suadesalocação (deleção).

Memória

slide 62

Classificação das Variáveis

Variáveis GlobaisVariáveis LocaisVariáveis Heap-Dinâmicas Explícitas

Memória

slide 63

– uso de variáveis globais (e estáticas):• espaço reservado para uma variável global existeenquanto o programa estiver sendo executado

– uso de variáveis locais:• espaço existe apenas enquanto a função que declaroua variável está sendo executada• liberado para outros usos quando a execução da funçãotermina

– variáveis globais ou locais podem ser simples ou vetores:• para vetor, é necessário informar o número máximo deelementos pois o compilador precisa calcular o espaço aser reservado

Memória

slide 64

– alocação dinâmica:• espaço de memória é requisitada em tempo deexecução• espaço permanece reservado até que sejaexplicitamente liberado

– depois de liberado, espaço estará disponibilizado para outrosusos e não pode mais ser acessado

– espaço alocado e não liberado explicitamente, seráautomaticamente liberado quando ao final da execução

Memória

slide 65

– memória estática:• código do programa• variáveis globais• variáveis estáticas

– memória dinâmica:• variáveis alocadas

dinamicamente• memória livre• variáveis locais

Memória

slide 66

– alocação dinâmica de memória:• usa a memória livre• se o espaço de memória livre formenor que o espaço requisitado,a alocação não é feita eo programa pode prevertratamento de erro

– pilha de execução:• utilizada para alocar memóriaquando ocorre chamada de função

– sistema reserva o espaçopara as variáveis locais da função– quando a função termina,espaço é liberado (desempilhado)

• se a pilha tentar crescer mais doque o espaço disponível existente,programa é abortado com erro

Memória

slide 67

Memória

slide 68

São alocadas automaticamente no início da execução doprograma;

São desalocadas automaticamente no final da execução doprograma.

Não ocorre overhead em tempo de execução para alocação edesalocação de memória!

Variáveis Globais

slide 69

São alocadas automaticamente no início da execução dosubprograma no qual foram declaradas;

São desalocadas automaticamente no final da execução dosubprograma no qual foram declaradas.

A alocação e desalocação destas variáveis é gerenciada pelo SO!

Variáveis Locais

slide 70

Uma variável heap-dinâmica explícita é uma variável dinâmicaque pode ser alocada e desalocada pelo programador aqualquer momento durante a execução do programa.

Uma variável heap é uma variável anônima, ou seja, sem nome,e por isso só pode ser acessada através de seu endereço.

São usadas freqüentemente para estruturas dinâmicas queprecisam crescer e encolher durante a execução.

Variáveis Heap-Dinâmicas Explícitas

slide 71

A alocação de uma variável heap-dinâmica explícita é feita poruma função chamada alocadora que retorna o endereço davariável heap alocada.

Sintaxe da função malloc do C:

void * malloc (size_t n_bytes)

Variáveis Heap-Dinâmicas Explícitas

slide 72

Malloc– recebe como parâmetro o número de bytes que se desejaalocar– retorna um ponteiro genérico para o endereço inicial da áreadememória alocada, se houver espaço livre:• ponteiro genérico é representado por void*• ponteiro é convertido automaticamente para o tipo apropriado• ponteiro pode ser convertido explicitamente– retorna um endereço nulo, se não houver espaço livre:• representado pelo símbolo NULL

Variáveis Heap-Dinâmicas Explícitas

slide 73

Função malloc do C

– Exemplo:void main () {int *ptrInt;...ptrInt = malloc(sizeof(int));...}

Variáveis Heap-Dinâmicas Explícitas

Cria uma variável heapdo tipo int e colocaseu endereço noponteiro ptrInt.

slide 74

Exemplo da função malloc do C

(i) int * ptrInt;

(ii) ptrInt = malloc(sizeof(int));

Variáveis Heap-Dinâmicas Explícitas

Variável do tipo int, anônima, alocada dinamicamente (HEAP).

slide 75

Variáveis Heap-Dinâmicas Explícitas

slide 76

Malloc– v armazena endereço inicial de uma área contínua dememória suficiente para armazenar 10 valores inteiros– v pode ser tratado como um vetor declarado estaticamente

• v aponta para o inicio da área alocada• v[0] acessa o espaço para o primeiro elemento• v[1] acessa o segundo• .... até v[9]

Variáveis Heap-Dinâmicas Explícitas

slide 77

Exemplo da função malloc do C

typedef struct {int dia, mes, ano;

} data;data *d;d = malloc (sizeof (data));d->dia = 31; d->mes = 12; d->ano = 2008;

Variáveis Heap-Dinâmicas Explícitas

slide 78

#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){// ponteiro para uma variável do tipo inteiroint *ponteiro;// aloca memória para um intponteiro = malloc(sizeof(int));// testa se a memória foi alocada com sucessoif(ponteiro)printf("Memoria alocada com sucesso.\n");

elseprintf("Nao foi possivel alocar a memoria.\n");

// atribui valor à memória alocada*ponteiro = 45;// obtém o valor atribuídoprintf("Valor: %d\n\n", *ponteiro);// libera a memóriafree(ponteiro);system("PAUSE");return 0;

}

Variáveis Heap-Dinâmicas Explícitas

slide 79

#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){int i;// quantidade de elementos na matrizint quant = 10;// ponteiro para o bloco de memóriaint *ponteiro;// aloca memória para uma matriz de inteirosponteiro = malloc(quant * sizeof(int));// testa se a memória foi alocada com sucessoif(ponteiro)printf("Memoria alocada com sucesso.\n");

else{printf("Nao foi possivel alocar a memoria.\n");exit(1);

}

Variáveis Heap-Dinâmicas Explícitas

// atribui valores aos elementos do arrayfor(i = 0; i < quant; i++){ponteiro[i] = i * 2;

}

// exibe os valoresfor(i = 0; i < quant; i++){printf("%d ", ponteiro[i]);

}

// libera a memóriafree(ponteiro);

printf("\n\n");system("PAUSE");return 0;

}

slide 80

Exemplo da função malloc do C

int *vector = NULL; /* declaração do ponteiro *//* alocação de memória para o vector */vector = (int*) malloc(25 * sizeof(int));/* altera o valor da posição dez para trinta e quatro */vector[10] = 34;free(vector); /* liberta a área de memória alocada */

Variáveis Heap-Dinâmicas Explícitas

slide 81

A desalocação de uma variável heap-dinâmica explícita é feitapor uma função chamada desalocadora.

Sintaxe da função free do C:

void free( void *)

Variáveis Heap-Dinâmicas Explícitas

slide 82

Free– recebe como parâmetro o ponteiro da memória a ser liberada

• a função free deve receber um endereço de memóriaque tenha sido alocado dinamicamente

Variáveis Heap-Dinâmicas Explícitas

slide 83

Exemplo da função free do C:void main () {int *ptrInt;...ptrInt = malloc(sizeof(int));...free(ptrInt);}

Variáveis Heap-Dinâmicas Explícitas

slide 84

Função free do C

– IMPORTANTE:• A função free não desaloca o ponteiro.

Ela desaloca apenas a variável heap cujo endereço estavaarmazenado no ponteiro;

• A função free também não “limpa” o ponteiro, ele permanececom o mesmo endereço, mas este se refere a uma variável quenão mais lhe pertence!

Variáveis Heap-Dinâmicas Explícitas

slide 85

– Uma variável heap permanece acessível enquanto houver umavariável do tipo ponteiro que armazene seu endereço.

Problemas– Referência Perdida– Variável Heap-Dinâmica Perdida(Lixo de Memória)

Variáveis Heap-Dinâmicas Explícitas

slide 86

Problemas - Referência Perdida:– É um ponteiro que contém o endereço de um variável heap-dinâmica desalocada

– Exemplo 1:void main(){float *ptr;…

ptr = malloc(sizeof(float));…

free(ptr);…printf(“%f”, *ptr); ⇐ Referência Perdida

}

Variáveis Heap-Dinâmicas Explícitas

slide 87

Problemas - Referência Perdida:

– Exemplo 2:void main(){float *ptr1, *ptr2;…ptr1 = malloc(sizeof(float));…ptr2 = ptr1;…free(ptr1);…*ptr2 = 15.9; ⇐ Referência Perdida

Variáveis Heap-Dinâmicas Explícitas

slide 88

Problemas– Heap-Dinâmica Perdida:

• É uma variável heap-dinâmica alocada porém não maisacessível.

• Também conhecida como lixo de memória

Variáveis Heap-Dinâmicas Explícitas

slide 89

Problemas - Heap-Dinâmica Perdida:

– Exemplo:void main(){int *ptr1, i;...

for(i = 0; i < 10; i++){ptr1 = malloc(sizeof(int)); ⇐ cria lixo*ptr1 = i;

}...}

Variáveis Heap-Dinâmicas Explícitas

slide 90

Exercícios:– Dada a variável float *pont_notas, alocar dinamicamenteespaço para armazenar 5 notas, ler as 5 notas e imprimira primeira e a quinta nota lidas.

– Fazer um programa que permita a entrada de dez números eque diga qual é o maior e o menor número. Use ponteiro ealocação dinâmica de memória.

Variáveis Heap-Dinâmicas Explícitas

slide 91

Exercícios:– Escreva um programa que leia um número inteiro positivo nseguido de n números inteiros e imprima esses n números emordem invertida.Por exemplo, ao receber 5 222 333 444 555 666 o seuprograma deve imprimir 666 555 444 333 222. O seu programanão deve impor limitações sobre o valor de n.

Variáveis Heap-Dinâmicas Explícitas

Referências

• Material Professora Karina Oliveira (Unicap)• Introdução a Estruturas de Dados - com técnicas

de programação em CW. Celes, R. Cerqueira, J.L. RangelEd. Campus - ISBN 85-352-1228-0

• Material Professor Marco A. Casanova - PUC-Rio • C Completo e Total - 3ª ed. - Herbert Schildt -

Makron Books

slide 92

slide 93

Estrutura de Dados I

UNICAP

Eduardo Araújo Oliveirahttp://eduoliveira.com

Recommended