93
Estrutura de Dados I UNICAP Eduardo Araújo Oliveira http://eduoliveira.com Twitter: @oliveiraeduardo

Ponteiros e Alocação Dinâmica

Embed Size (px)

Citation preview

Page 1: Ponteiros e Alocação Dinâmica

slide 1

Estrutura de Dados I

UNICAP

Eduardo Araújo Oliveirahttp://eduoliveira.com

Twitter: @oliveiraeduardo

Page 2: Ponteiros e Alocação Dinâmica

slide 2

PONTEIROS

Page 3: Ponteiros e Alocação Dinâmica

slide 3

“Memória?”

Page 4: Ponteiros e Alocação Dinâmica

slide 4

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

(ou posições)

Page 5: Ponteiros e Alocação Dinâmica

slide 5

“Uma variável é um aglomerado de

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

Page 6: Ponteiros e Alocação Dinâmica

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

Page 7: Ponteiros e Alocação Dinâmica

slide 7

Page 8: Ponteiros e Alocação Dinâmica

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

Page 9: Ponteiros e Alocação Dinâmica

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

Page 10: Ponteiros e Alocação Dinâmica

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

Page 11: Ponteiros e Alocação Dinâmica

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;

Page 12: Ponteiros e Alocação Dinâmica

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

Page 13: Ponteiros e Alocação Dinâmica

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

Page 14: Ponteiros e Alocação Dinâmica

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

Page 15: Ponteiros e Alocação Dinâmica

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

Page 16: Ponteiros e Alocação Dinâmica

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

Page 17: Ponteiros e Alocação Dinâmica

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

Page 18: Ponteiros e Alocação Dinâmica

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

Page 19: Ponteiros e Alocação Dinâmica

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

Page 20: Ponteiros e Alocação Dinâmica

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

Page 21: Ponteiros e Alocação Dinâmica

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

Page 22: Ponteiros e Alocação Dinâmica

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

Page 23: Ponteiros e Alocação Dinâmica

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

Page 24: Ponteiros e Alocação Dinâmica

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.

Page 25: Ponteiros e Alocação Dinâmica

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

Page 26: Ponteiros e Alocação Dinâmica

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

Page 27: Ponteiros e Alocação Dinâmica

Aritmética de ponteiros

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

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

slide 27

Page 28: Ponteiros e Alocação Dinâmica

Aritmética de ponteiros

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

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

slide 28

Page 29: Ponteiros e Alocação Dinâmica

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

Page 30: Ponteiros e Alocação Dinâmica

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

Page 31: Ponteiros e Alocação Dinâmica

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

Page 32: Ponteiros e Alocação Dinâmica

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

Page 33: Ponteiros e Alocação Dinâmica

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

Page 34: Ponteiros e Alocação Dinâmica

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

Page 35: Ponteiros e Alocação Dinâmica

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;

Page 36: Ponteiros e Alocação Dinâmica

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

Page 37: Ponteiros e Alocação Dinâmica

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

Page 38: Ponteiros e Alocação Dinâmica

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

Page 39: Ponteiros e Alocação Dinâmica

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

Page 40: Ponteiros e Alocação Dinâmica

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

Page 41: Ponteiros e Alocação Dinâmica

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

Page 42: Ponteiros e Alocação Dinâmica

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

Page 43: Ponteiros e Alocação Dinâmica

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

Page 44: Ponteiros e Alocação Dinâmica

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

Page 45: Ponteiros e Alocação Dinâmica

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

Page 46: Ponteiros e Alocação Dinâmica

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

Page 47: Ponteiros e Alocação Dinâmica

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

Page 48: Ponteiros e Alocação Dinâmica

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

Page 49: Ponteiros e Alocação Dinâmica

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

Page 50: Ponteiros e Alocação Dinâmica

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

Page 51: Ponteiros e Alocação Dinâmica

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

Page 52: Ponteiros e Alocação Dinâmica

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

Page 53: Ponteiros e Alocação Dinâmica

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

Page 54: Ponteiros e Alocação Dinâmica

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

Page 55: Ponteiros e Alocação Dinâmica

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

Page 56: Ponteiros e Alocação Dinâmica

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

Page 57: Ponteiros e Alocação Dinâmica

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

Page 58: Ponteiros e Alocação Dinâmica

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

Page 59: Ponteiros e Alocação Dinâmica

slide 59

ALOCAÇÃODINÂMICA

Page 60: Ponteiros e Alocação Dinâ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

Page 61: Ponteiros e Alocação Dinâmica

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

Page 62: Ponteiros e Alocação Dinâmica

slide 62

Classificação das Variáveis

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

Memória

Page 63: Ponteiros e Alocação Dinâmica

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

Page 64: Ponteiros e Alocação Dinâmica

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

Page 65: Ponteiros e Alocação Dinâmica

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

Page 66: Ponteiros e Alocação Dinâmica

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

Page 67: Ponteiros e Alocação Dinâmica

slide 67

Memória

Page 68: Ponteiros e Alocação Dinâmica

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

Page 69: Ponteiros e Alocação Dinâmica

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

Page 70: Ponteiros e Alocação Dinâmica

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

Page 71: Ponteiros e Alocação Dinâmica

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

Page 72: Ponteiros e Alocação Dinâmica

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

Page 73: Ponteiros e Alocação Dinâmica

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.

Page 74: Ponteiros e Alocação Dinâmica

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

Page 75: Ponteiros e Alocação Dinâmica

slide 75

Variáveis Heap-Dinâmicas Explícitas

Page 76: Ponteiros e Alocação Dinâmica

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

Page 77: Ponteiros e Alocação Dinâmica

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

Page 78: Ponteiros e Alocação Dinâmica

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

Page 79: Ponteiros e Alocação Dinâmica

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;

}

Page 80: Ponteiros e Alocação Dinâmica

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

Page 81: Ponteiros e Alocação Dinâmica

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

Page 82: Ponteiros e Alocação Dinâmica

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

Page 83: Ponteiros e Alocação Dinâmica

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

Page 84: Ponteiros e Alocação Dinâmica

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

Page 85: Ponteiros e Alocação Dinâmica

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

Page 86: Ponteiros e Alocação Dinâmica

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

Page 87: Ponteiros e Alocação Dinâmica

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

Page 88: Ponteiros e Alocação Dinâmica

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

Page 89: Ponteiros e Alocação Dinâmica

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

Page 90: Ponteiros e Alocação Dinâmica

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

Page 91: Ponteiros e Alocação Dinâmica

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

Page 92: Ponteiros e Alocação Dinâmica

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

Page 93: Ponteiros e Alocação Dinâmica

slide 93

Estrutura de Dados I

UNICAP

Eduardo Araújo Oliveirahttp://eduoliveira.com