programação i - alged.webnode.com · ponteiros •para trabalhar com a memória apontada pelo...
TRANSCRIPT
Programação I Ponteiros e alocação dinâmica de memória
Prof. Carlos Alberto
Ponteiros
• O ponteiro é um tipo de dado como int, char ou
float;
• Variáveis do tipo ponteiro são destinadas a
guardar e manipular endereços de memória;
• Por meio do endereço pode-se acessar a
informação, dizendo que a variável ponteiro
aponta para uma posição de memória.
Ponteiros
• Operador &: operador unário que devolve o
endereço na memória de seu operando.
Exemplo: ptr = &cont;
• Guarda o endereço na memória da variável cont em
ptr;
• Esse endereço é a posição interna da variável na
memória do computador e não tem nenhuma relação
com o valor de cont.
• O operador & tem como significado “o endereço de”.
Ponteiros
• Operador *: operador unário que devolve o valor
da variável localizada no endereço que o segue.
• Por exemplo, se ptr contém o endereço da
variável cont:
q = *ptr;
coloca o valor de cont em q.
• O operador * tem como significado “no
endereço de”.
Ponteiros
• A declaração de uma variável ponteiro é dada
pela colocação de um asterisco (*) na frente de
uma variável de qualquer tipo:
• Exemplo:
int *ptr; float *q
• Na linguagem C, é possível definir ponteiros para
os tipos básicos ou estruturas.
Ponteiros
• A definição de um ponteiro não reserva espaço
de memória para o seu valor e sim para o seu
conteúdo.
• Antes de utilizar um ponteiro, o mesmo deve ser
inicializado.
• Deve ser colocado um endereço de memória válido
para ser acessado posteriormente.
Ponteiros
• Um ponteiro pode ser utilizado de duas maneiras
distintas:
• Trabalhar com o endereço armazenado no ponteiro;
• Trabalhar com a área de memória apontada pelo
ponteiro.
• Para trabalhar com o endereço armazenado no
ponteiro, utiliza-se o seu nome sem o asterisco
na frente.
• Assim qualquer operação realizada será feita no
endereço do ponteiro.
Ponteiros
• Para trabalhar com a memória apontada pelo
ponteiro, alterando ou acessando este valor
deve-se colocar um asterisco antes do nome
do ponteiro.
• Assim, qualquer operação realizada será feita no
endereço de memória apontado pelo ponteiro.
Ponteiros
• Maior problema em relação ao ponteiro
• Entender quando se está trabalhando com o seu valor,
ou seja, o endereço;
• Entender quando se está trabalhando com a
informação apontada por ele.
Ponteiros
• Aritmética de ponteiros
• É possível realizar operações de soma e subtração
com variáveis do tipo ponteiro;
• A quantidade de endereços de memória relativos ao
tipo do ponteiro será somada ou subtraída no ponteiro.
• Exemplo: um ponteiro para int ocupa 4 bytes, uma
operação de soma acrescentará 4 posições na
memória;
Ponteiros
• Vetores como ponteiros em C
• Vetores são ponteiros com alocação estática de
memória;
• Todo vetor na linguagem C é um ponteiro;
• Através da aritmética de ponteiros é possível acessar
os índices do vetor;
• Formas para se obter o endereço (ponteiro) do
início de um vetor:
&vet[0];
vet;
Alocação de memória
• Alocação estática
• Ocorre em tempo de compilação;
• No momento em que se define uma variável ou
estrutura é necessário definir seu tipo e tamanho;
• A memória alocada fica disponível até o término do
programa (rotina ou função).
Alocação de memória
• Alocação dinâmica
• Ocorre em tempo de execução;
• As variáveis e estruturas são declaradas sem a
necessidade de se definir seu tamanho;
• Durante a execução do programa a memória será
reservada e no momento em que não for mais
necessária, deve ser liberada.
Alocação de memória
• A alocação dinâmica é feita com o auxílio de
comandos ou funções que permitem reservar
e/ou liberar memória.
• Na linguagem C, a alocação dinâmica de
memória pode ser realizada com apenas quatro
chamadas a funções:
• malloc
• calloc
• realloc
• free
Alocação de memória
• Função malloc
• Permite a alocação de uma nova área de memória;
• Parâmetro: quantidade de bytes para alocação.
•
• Retorna, se existir memória suficiente, um endereço
que para uma variável do tipo ponteiro.
• Retorna um ponteiro para o tipo void, deve-se utilizar o
typecast, transformando este endereço para o tipo de
ponteiro desejado.
Alocação de memória
• Função calloc
• Tem a mesma funcionalidade de malloc;
• Parâmetros: a quantidade de posições a serem
alocadas e o tamanho do tipo de dado;
• Além de alocar o espaço, também inicializa o mesmo
com zeros.
Alocação de memória
• Função realloc
• Permite que uma área previamente alocada seja
aumentada ou diminuída;
• Parâmetro: o ponteiro retornado pelo malloc e a
indicação do novo tamanho;
• O novo tamanho pode ser maior ou menor que o
original;
Alocação de memória
• Função realloc
• A realocação de memória pode resultar na troca de
blocos na memória.
• Um ponteiro para o bloco é devolvido porque realloc()
pode precisar mover o bloco para aumentar seu
tamanho.
• Se isso ocorrer, o conteúdo do bloco antigo é copiado
para o novo bloco, e nenhuma informação é perdida.
Alocação de memória
• Função free
• Libera uma área alocada previamente com a função
malloc, calloc ou realloc;
• Parâmetro: o endereço que se deseja liberar;
• Quando alocamos memória dinamicamente é
necessário que nós a liberemos quando ela não for
mais necessária.
Alocação de arrays
• Para armazenar um array o compilador C calcula
o tamanho, em bytes, necessário e reserva
posições sequenciais na memória
• Note que isso é muito parecido com alocação dinâmica
• Existe uma ligação muito forte entre ponteiros e
arrays.
• O nome do array é apenas um ponteiro que aponta
para o primeiro elemento do array.
Alocação de arrays
• Ao alocarmos memória estamos, na verdade, alocando um array.
0 1 ... 99
p
Alocação de arrays
• Note, no entanto, que o array alocado possui
apenas uma dimensão
• Para liberá-lo da memória, basta chamar a
função free() ao final do programa:
Alocação de arrays
• Para alocarmos arrays com mais de uma
dimensão, utilizamos o conceito de “ponteiro
para ponteiro”.
• Ex.: char ***p3;
• Para cada nível do ponteiro, fazemos a alocação
de uma dimensão do array.
Alocação de arrays
• Conceito de “ponteiro para ponteiro”:
Memória
posição variável conteúdo
119
120 char ***p3 122
121
122 char **p2 124
123
124 char *p1 126
125
126 char letra ‘a’
127
Alocação de arrays • Em um ponteiro para ponteiro, cada nível do ponteiro permite criar uma nova dimensão no array. Memória
posição variável conteúdo
119 int **p 120
120 p[0] 123
121 p[1] 126
122
123 p[0][0] 69
124 p[0][1] 74
125
126 p[1][0] 14
127 p[1][1] 31
128
Alocação de arrays • Em um ponteiro para ponteiro, cada nível do ponteiro permite criar uma nova dimensão no array.
int*
int*
int*
int*
int*
int*
int*
int*
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
1º malloc:
cria as linhas
2º malloc:
cria as colunas
int **p; int **p;
Alocação de arrays
• Diferente dos arrays de uma dimensão, para
liberar um array com mais de uma dimensão da
memória, é preciso liberar a memória alocada em
cada uma de suas dimensões, na ordem inversa
da que foi alocada
Alocação de arrays
Referências
BACKES, André. Linguagem C: completa e
descomplicada. Editora Campus/Elsevier, 2012.
LAUREANO, Marcos. Estrutura de Dados com
Algoritmos e C. Rio de Janeiro: Brasport, 2008.