Buscar

Aula 13 - ponteiros- alocacao

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 22 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

4/2/2020 Linguagem C 1
LTP II
Ponteiros e Alocação Dinâmica 
de Memória
4/2/2020 Linguagem C 2
Alocação dinâmica de memória
• Alocação dinâmica é o meio pelo qual um programa pode 
obter memória enquanto está em execução.
• Em geral a alocação é utilizada quando não se sabe a 
quantidade de dados que serão armzanenados durante a 
execução do programa, o que requer tipos e estruturas de 
dados de qualquer tamanho e modificáveis durante a 
execução de programas;
• Exemplos são matrizes dinâmicas e listas encadeadas.
• A memória alocada dinamicamente é obtida do heap 
(região de memória que está entre o programa e a pilha).
4/2/2020 Linguagem C 3
Alocação dinâmica (malloc)
• Funções para alocação dinâmica:
#include <stdlib.h>
void *malloc( size_t numero de bytes); 
aloca dinamicamente uma porção contínua da memória com 
tamanho igual ao número de bytes especificado retornando um 
ponteiro para o bloco alocado. Se não for possível alocar 
memória é retornado um ponteiro nulo (NULL).
O ponteiro retornado é do tipo void, o que faz com que possa ser 
convertido em qualquer outro tipo de ponteiro em C.
Exemplo:
char *c;
c= (char *) malloc (6);
Retorna um ponteiro para uma área de memória de 6 bytes 
acessível por um ponteiro do tipo char.
4/2/2020 Linguagem C 4
Alocação dinâmica (malloc)
• Dependendo do tipo de variável que se deseja armazenar, 
a quantidade de bytes necessário por variável a ser alocada 
varia;
• Por exemplo, uma variável float necessita de quatro bytes, 
enquanto uma int de 2 ou 4 bytes;
• Para facilitar a alocação de memória, pode-se utilizar a 
função sizeof (), cuja sintaxe é:
– int sizeof(tipo)
• Exemplos:
malloc (10 * sizeof (int)); 
// aloca 20 bytes para 10 variáveis do tipo int
malloc (10 * sizeof (float)); 
// aloca 40 bytes para 10 variáveis do tipo float
4/2/2020 Linguagem C 5
Alocação dinâmica (malloc)
• Uma sintaxe importante no uso da função malloc é a 
conversão de tipo;
• Alguns compiladores não aceitam que o ponteiro retornado 
pela função seja igualado a uma variável sem conversão;
• Para evitar erros de sintaxe, é recomendável converter o 
tipo retornado da seguinte maneira:
variável_ponteiro = (tipo_ponteiro *) malloc (...);
• Exemplo:
int *p;
float *f;
p = (int *) malloc (10 * sizeof (int));
f = (float *) malloc (10 * sizeof (float));
4/2/2020 Linguagem C 6
Alocação dinâmica (malloc)
• A função malloc não efetua inicialização da área de 
memória alocada.
• Uma área de memória alocada utilizando malloc pode ser 
utilizada como uma matriz, cujo tamanho pode ser 
configurado em tempo de execução.
• Exemplo:
int *p;
p = (int *) malloc (15 * sizeof (int));
*p=1; // ou p[0] = 1==> altera o valor do elemento p[0]
*(p+2)=3; // ou p[2] = 3===>altera o valor do elemento p[2]
printf(“p[0] = %d p[2] = %d\n”, p[0],p[2]);
4/2/2020 Linguagem C 7
Alocação dinâmica (malloc)
• Podem ocorrer erros durante a alocação; por exemplo, 
pode não haver memória alocável disponível;
• Caso o erro ocorra, o comando malloc retorna um ponteiro 
Nulo;
• É recomendável que, após a alocação, seja efetuado um 
teste para checar se a alocação foi realizada com sucesso;
• Exemplo:
int *iptr;
iptr = (int *)malloc(10 * sizeof(int));
if (iptr == NULL)
{ ...Tratamento do Erro... }
4/2/2020 Linguagem C 8
Alocação dinâmica (malloc)
• Exercício
– Implemente um cadastro de clientes de uma loja observando o 
seguinte:
• Os dados dos clientes devem ser armazenados em um vetor;
• A quantidade máxima não está definida. Deve ser informada pelo 
usuário no início do programa;
• De cada cliente devem ser armazenados o nome e a idade;
• No momento do cadastramento de cada cliente deve ser informado, 
pelo usuário, a quantidade máxima de caracteres do nome do cliente;
• Devem ser implementadas as operações de cadastramento de clientes 
e consulta ao cadastro (pelo índice do vetor). 
4/2/2020 Linguagem C 9
Alocação dinâmica (calloc)
• Existe uma outra função análoga a malloc.
Sintaxe:
void *calloc( size_t numero itens,size_t tamanho do item); 
aloca dinamicamente uma porção contínua da memória com 
tamanho em bytes igual o produto de numero itens * tamanho de 
cada item, retornando um ponteiro para o bloco alocado. Se não 
for possível alocar memória é retornado um ponteiro nulo 
(NULL).
O ponteiro retornado é do tipo void, o que faz com que possa ser 
convertido em qualquer outro tipo de ponteiro em C. A função 
calloc inicializa o bloco de dados alocados com 0 (zero).
Exemplo :
int *p;
p=(int *) calloc (100, sizeof (int)); 
4/2/2020 Linguagem C 10
Alocação dinâmica (realloc)
• Blocos de Memória previamente alocados com malloc () e 
calloc() também podem ter ser tamanho alterado 
posteriormente com a função realloc();
Sintaxe :
void *realloc (void *ptr, size_t numero de bytes);
Modifica o tamanho da memória alocada para ptr para o novo 
tamanho especificado. Se o bloco de memória não puder ter 
seu tamanho alterado, a função realloc() alocará, se possível, 
um novo bloco de memória e copiando o conteúdo do bloco já 
existente para o novo bloco alocadao
Se ptr é igual a NULL a realloc funciona igual a malloc.
Se numero de bytes for zero, o ponteiro ptr é liberado análogo ao 
free.
Se não houver memória suficiente a função retorna nulo e o 
bloco original é preservado.
4/2/2020 Linguagem C 11
Alocação dinâmica (free)
• Após a utilização de um bloco de memória, o mesmo não 
é novamente alocado até ser liberado em tempo de 
execução com a função free;
Sintaxe:
void free( void *p);
A função free toma um ponteiro como argumento e libera a 
memória para a qual o ponteiro aponta;
Exemplo:
int *iptr;
iptr = (int *)malloc(10 * sizeof(int));
if (iptr == NULL)
{ ...Tratamento do Erro... }
......... free(iptr);
4/2/2020 Linguagem C 12
Alocação dinâmica (Uso de Malloc)
char *pChar;
int *pInt, nroChar, nroInt;
printf(“ Numero de caracteres a serem alocados\n”); scanf(“%d”, &nroChar);
if ( !(pChar =(char*) malloc (nroChar *sizeof(char))))
printf(“nao foi possivel alocar memoria\n”);
else
printf(“alocacao realizada com sucesso\n”);
printf(“ Numero de elementos inteiros a alocar\n”); scanf(“%d”, &nroInt); 
if (pInt = (int*) calloc(nroInt, sizeof(int))){
for (i=0; i< nroInt) pInt[i] = i*i; 
printf(“valores\n”); 
for (i=0; i< nroInt) printf(“ %10d”, pInt[i]); printf(“\n”);
}
else
printf(“erro de alocacao de memoria\n”);
free (pChar); free (pInt);
4/2/2020 Linguagem C 13
Alocação dinâmica (Uso de Malloc)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void leMatriz(int *z, int n);
void escreveMatriz( int *z, int n);
void main (void)
{
int *x, nroElem;
printf(“digite o nro de elementos a serem 
lidos \n”);
scanf(“%d”, &nroElem);
x= (int*) malloc(nroElem * sizeof(int));
if(x){
leMatriz (x,nroElem);
escreveMatriz(x, nroElem);
free(x);}
else printf(“Erro de alocacao\n”);
getch();
}
void leMatriz(int *z, int n) 
{
for (int i=0; i<n; i++)
{
printf(“Digite o elemento [%d] =”,
i+1);
scanf(“%d”, &z[i]);
}
}
void escreveMatriz( int *z, int n)
{
printf(“Matriz lida \n”);
for (int i=0; i<n;i++)
printf(“%10d”, *(z+i));
printf(“\n”);
}
4/2/2020 Linguagem C 14
Alocação dinâmica (Uso de Realloc)
#include <stdio.h> 
#include <conio.h>
#include <stdlib.h>
void leMatriz(int *z, int n);
void main(void)
{
float *p,*novop;
int nroElem,novoNroElem;
printf("Digite o numero de elementos da matriz = ");
scanf("%d",&nroElem);
p= (float *) malloc(nroElem*sizeof(float));
if (!p)
printf("erro de alocacao dos %d elementos \n", nroElem);
else
{
for (int i=0; i<nroElem;i++)
p[i] = i+1;
4/2/2020 Linguagem C 15
Alocação dinâmica (Uso de Realloc)
printf("Digite o novo numero de elementos da matriz = ");
scanf("%d",&novoNroElem);
novop= (float *) realloc(p, novoNroElem * sizeof(float));
if (!novop)
{
printf("erro de realocacao dos %d elementos \n", novoNroElem);
free(p);
}
else{ 
p= novop;
for(inti=nroElem;i<novoNroElem;i++)
p[i] = i+1;
for (int i=0; i<novoNroElem;i++)
printf("Elemento [%4d] = %10.2f\n",i+1,p[i]);
free (p);} } getch();}
4/2/2020 Linguagem C 16
Alocação dinâmica (Uso Calloc e Realloc)
int num =10, *matriz,cont,*matriz2;
if((matriz = (int *) calloc (num, sizeof(int))) {
printf ("Os elementos atuais da matriz e seus enderecos sao:\n");
for (cont=0;cont < num;cont++) {
matriz[cont]=cont;
printf ("%d\t%x\n",matriz[cont],&matriz[cont]); 
}
if((matriz 2= (int *) realloc (matriz, num-5))
{
printf ("Apos a realocação, os elementos da matriz e seus enderecos sao:\n");
for (cont=0;cont < num-5;cont++){
matriz[cont]=cont*cont;
printf ("%d\t%x\n",matriz[cont], &matriz[cont]);
}
free (matriz2);
}
else
free(matriz); // erro de alocacao de matriz2
} 
4/2/2020 Linguagem C 17
Ponteiros para ponteiros
• Quando um ponteiro contém o endereço de uma variável 
dizemos que existe uma indireção simples.
Exemplo :
float *p, maior;
p = &maior ;
• Um ponteiro pode apontar para um outro ponteiro. Neste 
diz-se que temos uma indireção múltipla ou ponteiro para 
ponteiro. 
Endereço Valor
Ponteiro Váriável
Endereço Endereço Valor
Ponteiro Ponteiro Variável
4/2/2020 Linguagem C 18
Ponteiros para ponteiros
• Variáveis do tipo ponteiro para ponteiro são declaradas 
como :
tipo_do_ponteiro ** nome_do_ponteiro;
void main (void)
{
float a = 50.35, *pa, **ppa;
pa = &a; // pa armazena o endereço da variável a
ppa = &pa; // ppa armazena o endereço do ponteiro pa
printf(“ a= %f \n”,a); // imprime o valor de a
printf(“ a = %f\n”, *pa); // imprime o valor de a usando pa
printf(“ a= %f\n”, **ppa); // imprime o valor de a usando ppa
}
4/2/2020 Linguagem C 19
Ponteiros para ponteiros
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void aloca (float **pMat, int n);
void desaloca (float *pMat);
void leNotas(float *notas, int nroAlunos);
int main (void){
float *notas;
int nroAlunos;
printf("Digite o numero de alunos= ");
scanf("%d", &nroAlunos);
aloca (&notas, nroAlunos);
if (!notas)
{
printf("Erro de alocacao\n");
exit(0);
}
leNotas(notas,nroAlunos);
for (int i=0; i<nroAlunos;i++)
printf("Nota [%d] = %.2f\n", i+1, 
notas[i]);
desaloca(notas);
getch();
}
void aloca (float **pMat, int n){
*pMat = (float*) malloc(n * sizeof(float));
}
void desaloca (float *pMat){
free(pMat);
}
void leNotas(float *notas, int nroAlunos){
for (int i=0; i<nroAlunos;i++){
printf("Digite a nota do aluno %d = ", 
i+1);
scanf("%f",&notas[i]);}}
4/2/2020 Linguagem C 20
Matrizes de ponteiros
• Ponteiros podem ser organizados em matrizes como 
qualquer outro tipo de dado. A declaração de uma matriz 
de ponteiros é realizada como:
tipo_do_ponteiro *nome_do_ponteiro[Dimensão];
• Exemplo
void main (void){
int nro1, nro2=60, *pNro[2];
pNro[0] = &nro1;
pNro[1] = &nro2;
printf("Digite um numero inteiro= ");
scanf("%d",pNro[0]);
printf(" nro1 = %d %d %d \n", nro1,*pNro[0], pNro[0][0]);
printf(" nro2 = %d\n", *pNro[1]);
}
4/2/2020 Linguagem C 21
Matrizes de Ponteiros (usando como matrizes 
bidimensionais)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main (void){
int nCol,nLin;
float *a[20]; // float a[20][nCol]
printf("Digite o numero de linhas = ");
scanf("%d", &nLin); 
// nLin deve ser menor que 20
printf("Digite o numero de colunas = ");
scanf("%d", &nCol);
for (int i=0; i<nLin;i++) {
a[i] = (float *)malloc(nCol * 
sizeof(float) );
if (!a[i]){
printf("Erro na alocacao da linha 
%d \n");
getch();exit(0);}}
for (int i=0; i< nLin; i++) {
for (int j=0; j< nCol; j++) {
printf("Digite A[%d,%d] = ",i+1,j+1);
scanf("%f", &a[i][j]);
}
}
for (int i=0; i< nLin; i++){
for (int j=0; j< nCol; j++)
{
printf("A[%d,%d] = %.3f 
\n",i+1,j+1,a[i][j]);
}
free(a[i]);
}
getch();
}
4/2/2020 Linguagem C 22
Ponteiros para Ponteiros (usando como matrizes 
bidimensionais)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main (void)
{
int nCol,nLin;
float **a;
printf("Digite o numero de linhas = ");
scanf("%d", &nLin); 
printf("Digite o numero de colunas = ");
scanf("%d", &nCol);
a = (float **) malloc(nLin * 
sizeof(float*));
if(!a) {
printf("Erro na alocacao da matriz de 
linhas \n");
getch(); exit(0);}
for (int i=0; i<nLin;i++){
a[i] = (float *) malloc(nCol * 
sizeof(float));
if (!a[i]){
printf("Erro na alocacao da linha %d 
\n",i);
getch();exit(0);}
for (int i=0; i< nLin; i++){
for (int j=0; j< nCol; j++){
printf("Digite A[%d,%d] = ",i+1,j+1);
scanf("%f", &a[i][j]);}}
for (int i=0; i< nLin; i++){
for (int j=0; j< nCol; j++){
printf("A[%d,%d] = %.3f 
\n",i+1,j+1,a[i][j]);}
free(a[i]);}
free(a);
getch(); }

Outros materiais