exerc cios - aloca˘c~ao din^amica -...
TRANSCRIPT
Exercıcios - Alocacao Dinamica
Exercıcios - Alocacao Dinamica
Gilberto A. S. Segundo
Programacao Aplicada de ComputadoresEngenharia Eletrica
Universidade Federal do Espırito Santo - UFES
24 de agosto de 2011
1 / 23
Exercıcios - Alocacao Dinamica
Grupo de e-mail
Grupo de e-mail
Aceitem o convite para o grupo de e-mail!
2 / 23
Exercıcios - Alocacao Dinamica
Testando
Ferramentas de programacao
Crie uma pasta chamada teste dentro da pasta do seu usuario.
Como editor de texto, pode-se usar o gedit: Aplicativos->acessorios->gedit, ou simplesmente tecle ALT+F2 e digite gedit.
O terminal pode ser executado de diversas maneiras:
Aplicativos->acessorios->TerminalTecle ALT+F2 e digite gnome-terminal.Navegue ate a pasta onde esta o seu trabalho, clique com obotao direito em uma area vazia e escolha a opcao abrir numterminal.
3 / 23
Exercıcios - Alocacao Dinamica
Testando
Programa teste
Faca um programa que imprima a frase “Ola mundo” e salveo arquivo como main.c, dentro da pasta teste criada anterior-mente.
Abra um terminal nessa pasta e compile o programa manual-mente.
gcc main.c -o teste
Execute o programa: ./teste
4 / 23
Exercıcios - Alocacao Dinamica
Usando o Makefile
Usando o Makefile
Baixe o Makefile em: www.inf.ufes.br/˜gilbertosegundo e salveo arquivo na pasta teste.
Apague o arquivo executavel, recompile o programa e execute-ousando o Makefile:
make clean all run
5 / 23
Exercıcios - Alocacao Dinamica
Usando o Makefile
struct ponto
Crie o arquivo ponto.h com o seguinte conteudo:
1 #ifndef __PONTO_H
2 #define __PONTO_H
3
4 typedef struct ponto{
5 float x;
6 float y;
7 }Ponto;
8
9 #endif
6 / 23
Exercıcios - Alocacao Dinamica
Usando o Makefile
struct ponto
Adicione #include “ponto.h” no arquivo main.c
Crie um variavel do tipo Ponto chamada p1, inicialize suas coor-denadas com algum valor e imprima na tela essas coordenadas.
Exemplo
1 Ponto p1;
2 p1.x = 10;
3 p1.y = 25.859;
4 printf ("(%.2f, %.2f)\n",p1.x,p1.y);
7 / 23
Exercıcios - Alocacao Dinamica
Ponteiros
Ponteiro
Crie uma variavel x do tipo inteiro e inicialize-a;Crie um ponteiro para inteiro e faca-o apontar para a variavelcriada anteriormente.Imprima o valor da variavel x atraves do ponteiro.Leia um novo valor para a variavel x atraves do ponteiro eimprima-o.
1 int x = 50;
2 int *a;
3 a = &x;
4
5 printf ("x = %d\n", *a);
6 printf ("Digite um novo valor: ");
7 scanf ("%d",a);
8 //scanf ("%d",&(*a)); // & e um e comercial , acredite!
9 printf ("novo x = %d\n", *a);
8 / 23
Exercıcios - Alocacao Dinamica
Ponteiros
Ponteiro
No mesmo programa, crie um ponteiro para a variavel ponto.
Faca o ponteiro apontar para a variavel p1 criada anteriormentee imprima as coordenadas do ponto usando o ponteiro.
1 Ponto *p;
2 p = &p1;
3 printf ("(%.2f, %.2f)\n" ,(*p).x,(*p).y); // usando *
4 printf ("(%.2f, %.2f)\n",p->x,p->y); // usando ->
5 printf ("(%.2f, %.2f)\n" ,*p.x,*p.y); //est a correto?
9 / 23
Exercıcios - Alocacao Dinamica
Ponteiros
Ponteiro para struct ponto
Insira no ponto.h a cabecalho de uma funcao que recebe 2ponteiros para ponto e retorna a distancia entre eles.
1 float dist2Pontos (Ponto *p1 , Ponto *p2);
Crie o arquivo ponto.c e implemente essa funcao de distancia.
1 #include <math.h>
2 #include "ponto.h"
3
4 float dist2Pontos (Ponto *p1 , Ponto *p2){
5 return sqrt (pow(p1->x - p2->x,2) + pow (p1->y -
p2->y,2)) ;
6 }
10 / 23
Exercıcios - Alocacao Dinamica
Ponteiros
Ponteiro para struct ponto
Na main, crie um segundo ponto, inicialize-o e calcule a distanciaentre os pontos.
1 Ponto p2;
2 p2.x = 35.6;
3 p2.y = 85.98;
4 float dist = dist2Pontos (&p1 ,&p2);
5 printf ("Distancia = %f\n",dist);
Para compilar, adicione o ponto.o na variavel OBJECTS doMakefile
11 / 23
Exercıcios - Alocacao Dinamica
Ponteiro para void e valor especial NULL
Ponteiro para void
Pode-se declarar ponteiros (e apenas ponteiros) do tipo void,significando que o ponteiro aponta para qualquer objeto.
Como ele pode apontar para qualquer objeto, nao e possıvelfazer operacoes com o que o ponteiro esta apontando.
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main (){
4 int x=10;
5 void *p;
6 p = &x;
7 *p = 15; //n~ao compila!
8 // warning: dereferencing void * pointer
9 return 0;
10 }
12 / 23
Exercıcios - Alocacao Dinamica
Ponteiro para void e valor especial NULL
Ponteiro para void
O ponteiro void so serve para guardar o endereco de algo. Paramanipular o que ele aponta, devemos usar um ponteiro para otipo que ele esta apontando:
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main (){
4 int x=10;
5 void *p;
6 p = &x;
7 int *pi;
8 pi = (int*) p; // alguns compiladores aceitam sem
o (int*)
9 *pi = 15;
10 printf ("x = %d\n",x);
11 return 0;
12 }
13 / 23
Exercıcios - Alocacao Dinamica
Ponteiro para void e valor especial NULL
Ponteiro para void
O ponteiro void e usado normalmente como parametros e re-torno de funcao.
O cabecalho da funcao malloc e:
1 void *malloc(size_t size);
O tipo size t e geralmente um int. Note que a funcao recebe aquantidade de bytes que deve ser alocada e retorna um ponteirodo tipo void para essa area alocada. Essa funcao nao precisasaber para qual tipo ela esta alocando espaco, apenas o espacoque ela tem que alocar.
Para usarmos o espaco alocado por malloc temos que ter umponteiro para o tipo que queremos manipular.
14 / 23
Exercıcios - Alocacao Dinamica
Ponteiro para void e valor especial NULL
Valor especial NULL
Existe um valor especial para ponteiros, o NULL (letras maiusculas).
Qualquer ponteiro pode ter esse valor.
1 int *x = NULL;
2 ponto *p = NULL;
Ele significa que o ponteiro nao esta apontando para lugar al-gum. Um ponteiro inicializado com NULL e diferente de umponteiro nao inicializado!
1 int *x;
2 int *y = NULL;
15 / 23
Exercıcios - Alocacao Dinamica
Ponteiro para void e valor especial NULL
Valor especial NULL
Ponteiros NULL sao usados geralmente em comparacoes
1 if (p == NULL)
2 p = (int*) malloc (sizeof(int)*n);
16 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Memoria Dinamica
Aloque um vetor para 10 inteiros de forma dinamica e inicie asposicoes com algum valor.
1 #include <stdio.h>
2 #include <stdlib.h>
3 int main (){
4 int *v,n=10;
5 v = (int*) malloc (sizeof(int)*n);
6
7 int i;
8 for (i=0;i<n;i++)
9 v[i] = i*i;
10
11 for (i=0;i<n;i++)
12 printf ("v[%d] = %d\n",i, v[i]);
13
14 free (v);
15 return 0;
16 }17 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Usando o valgrind
Execute o valgrind para o programa anterior. No terminal,digite make free.
Se toda a memoria alocada foi desalocada, o valgrind imprimira:All heap blocks were freed – no leaks are possible
Se nao houve erros com a memoria alocada (acesso a posicoesindevidas, etc), o valgrind imprimira: ERROR SUMMARY: 0errors from 0 contexts
18 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Usando o valgrind
Faca o teste: exclua o comando free(v) do codigo anterior,recompile o programa e execute o valgrind:
make all free
1 ==5815== 40 bytes in 1 blocks are definitely lost
in loss record 1 of 1
2 ==5815== at 0x4025018: malloc (in /usr/lib/
valgrind/vgpreload_memcheck -x86 -linux.so)
3 ==5815== by 0x8048473: main (main.c:41)
4 ==5815== LEAK SUMMARY:
5 ==5815== definitely lost: 40 bytes in 1 blocks
6 ==5815== indirectly lost: 0 bytes in 0 blocks
7 ==5815== possibly lost: 0 bytes in 0 blocks
8 ==5815== still reachable: 0 bytes in 0 blocks
9 ==5815== suppressed: 0 bytes in 0 blocks
10 ==5815== ERROR SUMMARY: 1 errors from 1 contexts (
suppressed: 13 from 6)
11 }19 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Usando o valgrind
Outro teste: nao inicialize o vetor alocado e imprima o valor dealguma posicao
Conditional jump or move depends on uninitialised value(s)
Mais um teste: tente acessar uma posicao indevida no vetor.
Invalid read of size 4
20 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Ponteiro para ponteiro
Faca um vetor de strings, ou seja, um vetor de vetores, ou seja,uma matriz, usando memoria dinamica.
1 int main (){
2 char ** nomes;
3 int n=3, tamNomes = 20, i;
4 nomes = (char **) malloc (sizeof(char*)*n);
5 for (i=0;i<n;i++)
6 nomes[i] = (char*) malloc (sizeof(char)*
tamNomes);
7
8 for (i=0;i<n;i++)
9 free (nomes[i]);
10
11 free (nomes);
12 }
21 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Ponteiro para ponteiro
1 i n t main ( ){2 char ∗∗nomes , temp [ 1 0 0 ] ;3 i n t n=3, i ;4 nomes = ( char∗∗) m a l l o c ( s i z e o f ( char ∗)∗n ) ;5 f o r ( i =0; i<n ; i ++){6 p r i n t f ( "Digite o nome completo: " ) ;
7 s c a n f ( "%99[^\n]" , temp ) ; // l e a t e 99 c a r a c t e r e s . U l t i m o espa c o para o \08 s c a n f ( "%*[^\n]" ) ; // l e todo o b u f f e r a t e o e n t e r9 g e t c h a r ( ) ; // l e o e n t e r
10 nomes [ i ] = ( char ∗) m a l l o c ( s i z e o f ( char )∗( s t r l e n ( temp ) +1) ) ;11 s t r c p y ( nomes [ i ] , temp ) ;12 }13 f o r ( i =0; i<n ; i ++){14 p r i n t f ( "nome %d: " , i ) ;15 p u t s ( nomes [ i ] ) ;16 }1718 f o r ( i =0; i<n ; i ++)19 f r e e ( nomes [ i ] ) ;2021 f r e e ( nomes ) ;22 }
22 / 23
Exercıcios - Alocacao Dinamica
Memoria Dinamica
Exercıcios - Alocacao Dinamica
Gilberto A. S. Segundo
Programacao Aplicada de ComputadoresEngenharia Eletrica
Universidade Federal do Espırito Santo - UFES
24 de agosto de 2011
23 / 23