4. Uma memória é uma
seqüência de células
de armazenamento
(ou posições)
slide 4
5. “Uma variável é um
aglomerado de
uma ou mais células de
memória”.
slide 5
6. Variável
Atributos de uma variável
– nome: seqüência de caracteres utilizada para identificar a
variá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;
slide 6
8. Variável
– 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
slide 8
9. Variável
– 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
slide 9
10. Variável
– 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
slide 10
11. Variáveis do tipo ponteiro
Ponteiros, como o próprio nome diz, é um tipo de variável que
aponta 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 da
seguinte forma:
tipo_dado_apontado *nome_variavel;
– int *ptr1;
– char *ptr2;
slide 11
12. Variáveis do tipo ponteiro
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.
slide 12
13. Variáveis do tipo ponteiro
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 de
memória apontada. Operação chamada de indireção ou
desreferenciamento.
slide 13
14. Variáveis do tipo ponteiro
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
slide 14
15. Variáveis do tipo ponteiro
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*/
}
slide 15
16. Variáveis do tipo ponteiro
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);
}
slide 16
17. Variáveis do tipo ponteiro
*p ⇒ representa o conteúdo da variável apontada.
p ⇒ representa o endereço de memória da variável apontada.
slide 17
18. Variáveis do tipo ponteiro
Observação
– Quando queremos indicar que um ponteiro está “vazio”, ou
seja, não contém um endereço de uma variável, atribuímos
a 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*/
slide 18
19. Variáveis do tipo ponteiro
int a = 5, b = 7; (neste exemplo, um int ocupa 2bytes na
memoria, e não 4, como em outros exemplos).
int *ptr = NULL;
ptr = &a;
slide 19
20. Variáveis do tipo ponteiro
Atribuição
– Podemos atribuir o conteúdo de um ponteiro a outro. Dessa
forma, teremos dois ponteiros referenciando o mesmo endereço
de memória.
• Exemplo:
int a = 5, *p1, *p2;
p1 = &a;
p2 = p1;
slide 20
21. Aritmética de ponteiros
Sendo os ponteiros números que representam posições de
memória, podem ser realizadas algumas operações aritméticas
sobre eles:
– Incremento;
– Decremento;
– Diferença;
– Comparação.
slide 21
22. Aritmética de ponteiros
Incremento e Decremento
– Um ponteiro pode ser incrementado como qualquer outra
variável
– Se ptr é um ponteiro para um determinado tipo, quando ptr é
incrementado, por exemplo, de uma unidade, o endereço que
passa 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ço
anterior de ptr - sizeof(tipo) para que o ponteiro aponta
slide 22
24. Aritmética de ponteiros
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.
Somar 2 a um ponteiro de inteiros de 4 bytes irá incrementá-lo em 8. Isso faz
com que o incremento de um ponteiro o posicione para o próximo elemento em
um arranjo, o que geralmente é o resultado intencionado.
slide 24
25. 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 de
bytes) do objeto apontado.
• Exemplo: fator de escala de uma variável do tipo
float: 4
p = p + 2 significa p = p + 2 * fator de escala
slide 25
26. 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
27. Aritmética de ponteiros
Aritmética de Ponteiros
• Incremento: somar um a um ponteiro
• Exemplo:
float *p;
p++; OU ++p;
slide 27
28. Aritmética de ponteiros
Aritmética de Ponteiros
• Decremento: subtrair um de um ponteiro
• Exemplo:
float *p;
p--; OU --p;
slide 28
29. Aritmética de ponteiros
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”);
slide 29
30. Aritmética de ponteiros
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 y
y = *px + 1;
// y recebe o conteúdo do endereço de px+1
y = *(px + 1);
slide 30
31. Expressões com ponteiros
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!
slide 31
32. Aritmética de ponteiros
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 %dn", x, px);
printf("%i %dn", y, py);
printf("A diferenca entre eles eh: %d", py - px);
getchar();
slide 32
}
33. Ponteiro para estrutura
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;
slide 33
34. Ponteiro para estrutura
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
slide 34
36. Ponteiro para estrutura
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);
}
slide 36
37. Ponteiro para estrutura
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.
slide 37
38. Ponteiro e Vetor
O nome de um vetor corresponde ao endereço do seu primeiro
elemento, isto é, se v for um vetor então v é igual ao &v[0].
Embora o nome de um vetor seja um ponteiro para o primeiro
elemento do vetor, esse ponteiro não pode ser alterado durante
a execução do programa a que pertence.
slide 38
39. Ponteiro e Vetor
Existem duas formas de colocar um ponteiro apontando para o
primeiro elemento de um vetor:
int v[3] = {10, 20, 30};
int * ptr;
ptr = &v[0]; // ou
ptr = v;
slide 39
40. Ponteiro e Vetor
Ao contrário de v, que é um vetor (ponteiro constante associado
à sua própria memória), ptr é um ponteiro puro, e portanto
pode 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 */
slide 40
41. Ponteiro e Vetor
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’.
slide 41
42. Ponteiro e Vetor
Usando aritmética de ponteiros, como acessar os valores do
vetor 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();
}
slide 42
43. Ponteiro e Vetor
Usando a sintaxe de ponteiro e de vetor de que forma
poderemos 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();
} slide 43
44. Ponteiro e Vetor
Resumo
– Quando estamos manipulando ponteiros para vetores:
*c ⇒ representa o conteúdo da variável.
*(c + i) ⇒ representa o i-ésimo elemento do vetor referenciado
pelo ponteiro.
c[i] ⇒ também representa o i-ésimo elemento do vetor
referenciado pelo ponteiro.
c ⇒ representa o endereço de memória da variável.
slide 44
45. Ponteiro e Vetor
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));
slide 45
46. Passagem de Vetores para funções
Sempre que invocamos uma função e lhe passamos um vetor
como parâmetro, essa na realidade não recebe o vetor na sua
totalidade, mas apenas o endereço inicial do vetor, pois estamos
passando 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 recebe
um vetor como argumento aparece um ponteiro recebendo o
respectivo parâmetro.
slide 46
47. Passagem de Vetores para funções
#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();
}
slide 47
48. Ponteiro e Vetor
Conclusão
– Variáveis para vetores podem ser declaradas como sendo
apontadores, pois os elementos do vetor, individualmente, têm
o mesmo tratamento independente se a variável que os
armazena é um vetor ou um apontador.
char vetor[5] equivale a char *vetor;
– Versões com ponteiros são mais rápidas!
slide 48
49. Ponteiro e String
Pode-se criar e manipular uma string fazendo uso apenas de um
ponteiro.
Exemplo:
char *palavra = “exemplo”;
for(; *palavra != ‘0’; palavra++)
printf(“%c ”, *palavra);
slide 49
50. Ponteiro e String
Exercícios:
– Usando ponteiro para string escreva um função que mostre a
string 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 ponteiros
escreva uma função que calcule o comprimento de uma string
recebida por parâmetro. Obs.: Não pode usar a função strlen!
slide 50
51. Ponteiro para Ponteiro
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?
slide 51
52. Ponteiro para Ponteiro
Resposta:
– Suponha uma variável do tipo int chamada x
– Se quisermos armazenar seu endereço, declaramos um
ponteiro para o tipo da variável (int), isto é, colocamos um
asterisco entre o tipo da variável para que queremos apontar e
o nome do ponteiro
int *ptr_x;
– Se quisermos armazenar o endereço desse ponteiro, seguimos
exatamente os mesmos passos
int **ptr_ptr_x;
slide 52
53. Ponteiro para Ponteiro
Resposta:
– Os passos podem ser aplicados sucessivamente para qualquer
número de asteriscos
• int ****ptr = NULL; /* Válido */
– Ponteiro para ponteiro para ponteiro para ponteiro para
inteiro!
– Para chegar no destino final temos que fazer 4 indireções! Um
programa que use isso é difícil de entender e pode ficar muito
lento!
slide 53
54. Ponteiro para Ponteiro
#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 = %in", x, &x);
printf("x = %i e &x = %in", *ptr_x, ptr_x);
printf("x = %i e &x = %in", **ptr_ptr_x, *ptr_ptr_x);
getchar();
}
slide 54
55. Ponteiro para Ponteiro
int x = 5;
int * ptr_x;
int ** ptr_ptr_x;
/* Carga inicial dos ponteiros */
ptr_x = &x;
ptr_ptr_x = &ptr_x;
slide 55
56. Ponteiro para Ponteiro
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 um
ponteiro.
slide 56
57. Ponteiro para Ponteiro
ATENÇÃO
– Ponteiro é uma variável que não tem memória própria
associada, ela apenas contém o espaço para conter um
endereço.
– Portanto, só se pode utilizar o endereçamento através do
ponteiro depois que este está apontando para algum objeto já
existente.
– Não se deve fazer cargas iniciais de objetos apontados
por um ponteiro ainda não iniciado
– Exemplo:
int * p;
*p = 234;
slide 57
58. Ponteiro para Void
O termo void aplicado a um ponteiro significa um ponteiro que
pode 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();
slide 58
60. Memória
Alocação
– Processo de vinculação de uma variável de programa a uma
célula de memória de um pool de memória disponível
Desalocação
– Processo de devolução de uma célula de memória
desvinculada de uma variável ao pool de memória disponível
slide 60
61. Memória
Tempo de vida de uma variável é o tempo durante o qual
ela está vinculada a uma localização de memória específica;
Tempo de vida de uma variável é o intervalo de tempo
decorrente entre a sua alocação (criação) e a sua
desalocação (deleção).
slide 61
63. Memória
– uso de variáveis globais (e estáticas):
• espaço reservado para uma variável global existe
enquanto o programa estiver sendo executado
– uso de variáveis locais:
• espaço existe apenas enquanto a função que declarou
a variável está sendo executada
• liberado para outros usos quando a execução da função
termina
– variáveis globais ou locais podem ser simples ou vetores:
• para vetor, é necessário informar o número máximo de
elementos pois o compilador precisa calcular o espaço a
ser reservado
slide 63
64. Memória
– alocação dinâmica:
• espaço de memória é requisitada em tempo de
execução
• espaço permanece reservado até que seja
explicitamente liberado
– depois de liberado, espaço estará disponibilizado para outros
usos e não pode mais ser acessado
– espaço alocado e não liberado explicitamente, será
automaticamente liberado quando ao final da execução
slide 64
66. Memória
– alocação dinâmica de memória:
• usa a memória livre
• se o espaço de memória livre for
menor que o espaço requisitado,
a alocação não é feita e
o programa pode prever
tratamento de erro
– pilha de execução:
• utilizada para alocar memória
quando ocorre chamada de função
– sistema reserva o espaço
para as variáveis locais da função
– quando a função termina,
espaço é liberado (desempilhado)
• se a pilha tentar crescer mais do
que o espaço disponível existente,
programa é abortado com erro
slide 66
68. Variáveis Globais
São alocadas automaticamente no início da execução do
programa;
São desalocadas automaticamente no final da execução do
programa.
Não ocorre overhead em tempo de execução para alocação e
desalocação de memória!
slide 68
69. Variáveis Locais
São alocadas automaticamente no início da execução do
subprograma no qual foram declaradas;
São desalocadas automaticamente no final da execução do
subprograma no qual foram declaradas.
A alocação e desalocação destas variáveis é gerenciada pelo SO!
slide 69
70. Variáveis Heap-Dinâmicas Explícitas
Uma variável heap-dinâmica explícita é uma variável dinâmica
que pode ser alocada e desalocada pelo programador a
qualquer 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 que
precisam crescer e encolher durante a execução.
slide 70
71. Variáveis Heap-Dinâmicas Explícitas
A alocação de uma variável heap-dinâmica explícita é feita por
uma função chamada alocadora que retorna o endereço da
variável heap alocada.
Sintaxe da função malloc do C:
void * malloc (size_t n_bytes)
slide 71
72. Variáveis Heap-Dinâmicas Explícitas
Malloc
– recebe como parâmetro o número de bytes que se deseja
alocar
– retorna um ponteiro genérico para o endereço inicial da área
de
memó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
slide 72
73. Variáveis Heap-Dinâmicas Explícitas
Função malloc do C
– Exemplo:
void main () {
int *ptrInt;
...
ptrInt = malloc(sizeof(int));
...
}
Cria uma variável heap
do tipo int e coloca
seu endereço no
ponteiro ptrInt.
slide 73
74. Variáveis Heap-Dinâmicas Explícitas
Exemplo da função malloc do C
(i) int * ptrInt;
(ii) ptrInt = malloc(sizeof(int));
Variável do tipo int,
anônima, alocada
dinamicamente (HEAP).
slide 74
76. Variáveis Heap-Dinâmicas Explícitas
Malloc
– v armazena endereço inicial de uma área contínua de
memó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]
slide 76
77. Variáveis Heap-Dinâmicas Explícitas
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;
slide 77
78. Variáveis Heap-Dinâmicas Explícitas
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// ponteiro para uma variável do tipo inteiro
int *ponteiro;
// aloca memória para um int
ponteiro = malloc(sizeof(int));
// testa se a memória foi alocada com sucesso
if(ponteiro)
printf("Memoria alocada com sucesso.n");
else
printf("Nao foi possivel alocar a memoria.n");
// atribui valor à memória alocada
*ponteiro = 45;
// obtém o valor atribuído
printf("Valor: %dnn", *ponteiro);
// libera a memória
free(ponteiro);
system("PAUSE");
return 0;
} slide 78
79. Variáveis Heap-Dinâmicas Explícitas
#include <stdio.h> // atribui valores aos elementos do array
#include <stdlib.h> for(i = 0; i < quant; i++){
int main(int argc, char *argv[]) ponteiro[i] = i * 2;
{ }
int i;
// quantidade de elementos na matriz // exibe os valores
int quant = 10; for(i = 0; i < quant; i++){
// ponteiro para o bloco de memória printf("%d ", ponteiro[i]);
int *ponteiro; }
// aloca memória para uma matriz de inteiros
ponteiro = malloc(quant * sizeof(int)); // libera a memória
// testa se a memória foi alocada com sucesso free(ponteiro);
if(ponteiro)
printf("Memoria alocada com sucesso.n"); printf("nn");
else{ system("PAUSE");
printf("Nao foi possivel alocar a memoria.n"); return 0;
exit(1); }
}
slide 79
80. Variáveis Heap-Dinâmicas Explícitas
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 */
slide 80
81. Variáveis Heap-Dinâmicas Explícitas
A desalocação de uma variável heap-dinâmica explícita é feita
por uma função chamada desalocadora.
Sintaxe da função free do C:
void free( void *)
slide 81
82. Variáveis Heap-Dinâmicas Explícitas
Free
– recebe como parâmetro o ponteiro da memória a ser liberada
• a função free deve receber um endereço de memória
que tenha sido alocado dinamicamente
slide 82
84. Variáveis Heap-Dinâmicas Explícitas
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 estava
armazenado no ponteiro;
• A função free também não “limpa” o ponteiro, ele permanece
com o mesmo endereço, mas este se refere a uma variável que
não mais lhe pertence!
slide 84
85. Variáveis Heap-Dinâmicas Explícitas
– Uma variável heap permanece acessível enquanto houver uma
variável do tipo ponteiro que armazene seu endereço.
Problemas
– Referência Perdida
– Variável Heap-Dinâmica Perdida
(Lixo de Memória)
slide 85
86. Variáveis Heap-Dinâmicas Explícitas
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
}
slide 86
90. Variáveis Heap-Dinâmicas Explícitas
Exercícios:
– Dada a variável float *pont_notas, alocar dinamicamente
espaço para armazenar 5 notas, ler as 5 notas e imprimir
a primeira e a quinta nota lidas.
– Fazer um programa que permita a entrada de dez números e
que diga qual é o maior e o menor número. Use ponteiro e
alocação dinâmica de memória.
slide 90
91. Variáveis Heap-Dinâmicas Explícitas
Exercícios:
– Escreva um programa que leia um número inteiro positivo n
seguido de n números inteiros e imprima esses n números em
ordem invertida.
Por exemplo, ao receber 5 222 333 444 555 666 o seu
programa deve imprimir 666 555 444 333 222. O seu programa
não deve impor limitações sobre o valor de n.
slide 91
92. Referências
• Material Professora Karina Oliveira (Unicap)
• Introdução a Estruturas de Dados - com técnicas
de programação em C
W. Celes, R. Cerqueira, J.L. Rangel
Ed. 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
93. Estrutura de Dados I
UNICAP
Eduardo Araújo Oliveira
http://eduoliveira.com
slide 93