Função malloc

6.487 visualizações

Publicada em

Função malloc - com as anotações da aula no Smartboard

Publicada em: Diversão e humor
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Função malloc

  1. 1. Escola Secundária c/ 3º CEB da Batalha Alocação dinâmica de memória
  2. 2. Composição de Estruturas <ul><li>struct rectangulo { </li></ul><ul><li> struct ponto inicio; </li></ul><ul><li> struct ponto fim; </li></ul><ul><li>}; </li></ul><ul><li>struct rectangulo r = { { 10, 20 }, </li></ul><ul><li>{ 30 , 40 } </li></ul><ul><li>}; </li></ul><ul><li>Acesso aos dados: </li></ul><ul><li>r.inicio.x += 10; </li></ul><ul><li>r.inicio.y -= 10; </li></ul>r inicio x: y: 10 20 fim x: y: 30 40
  3. 3. Ponteiros para Estruturas <ul><li>Estruturas grandes são passadas como parâmetro </li></ul><ul><li>De forma mais eficiente através de ponteiros </li></ul><ul><li>struct ponto *pp; </li></ul><ul><li>struct ponto p1 = { 10, 20 }; </li></ul><ul><li>pp = &p1; </li></ul><ul><li>printf(“Ponto P1: (%d %d) ”, (*pp).x, (*pp).y}; </li></ul><ul><li>Aceder com o operador “->”: </li></ul><ul><li>printf(“Ponto P1: (%d %d) ”, pp->x, pp->y}; </li></ul><ul><li>(*pp).x == pp->x </li></ul>pp 1002 p1 x: y: 1002 10 20
  4. 4. Alocação Dinâmica de Memória <ul><li>incluir a biblioteca standard do C: stdlib.h (malloc() e free()) </li></ul><ul><li>possibilidade de libertar memória à medida que deixa de ser precisa </li></ul><ul><li>as funções calloc e malloc permitem alocar blocos de memória em tempo de execução </li></ul><ul><li>void * malloc( ); </li></ul><ul><li>/* </li></ul><ul><li>retorna um ponteiro void para n bytes de memória não iniciados. Se não há memória disponível malloc retorna NULL </li></ul><ul><li>*/ </li></ul>número de bytes alocados size_t n
  5. 5. Alocação Dinâmica de Memória <ul><li>A função malloc () ( memory allocation ) </li></ul><ul><li>reserva uma porção de memória, retornando um apontador genérico (tipo void *) para o ínicio da porção reservada, ou o valor NULL no caso da reserva ser impossível </li></ul><ul><li>A sua utilização é representada no exemplo seguinte: </li></ul><ul><li>int *pi; </li></ul><ul><li>pi= ( int *) malloc (sizeof( int )); </li></ul><ul><li>/* aloca espaço para um inteiro */ </li></ul>
  6. 6. malloc () – exemplo <ul><li>float *v; </li></ul><ul><li>int n; </li></ul><ul><li>printf(&quot;Quantos valores? &quot;); </li></ul><ul><li>scanf(&quot;%d&quot;, n); </li></ul><ul><li>v = (float *) malloc(n * sizeof(float) ); </li></ul><ul><li>Neste exemplo, é reservada uma porção de memória capaz de guardar n números reais ( float ), ficando o apontador v a apontar para o endereço inicial dessa porção de memória. O cast da função malloc() - (float *) - assegura que o apontador retornado é para o tipo especificado na declaração do apontador. Certos compiladores requerem obrigatoriamente o cast . </li></ul>Pág.424
  7. 7. malloc () <ul><li>Conselho: não altere o valor do apontador que recebeu o retorno da função malloc(). Desta forma poderá sempre saber onde começa o bloco de memória dinâmica reservado. Utilize apontadores auxiliares para realizar operações (leitura, escrita) dentro do bloco de memória. </li></ul>float *v,*paux; int n; printf(&quot;Quantos valores? &quot;); scanf(&quot;%d&quot;, n); v = (float *) malloc(n * sizeof(float) ); paux=v;
  8. 8. Libertar memória dinâmica <ul><li>A memória é libertada utilizando a função free() </li></ul><ul><li>int *pi; </li></ul><ul><li>pi= ( int *) malloc (sizeof( int )); </li></ul><ul><li>Para libertar a memória: </li></ul><ul><li>free(pi); </li></ul>
  9. 9. Exercícios <ul><li>1-Diga qual o output do seguinte programa: </li></ul><ul><ul><li>int *p; </li></ul></ul><ul><ul><li>p = (int *) malloc (sizeof(int)); ou (int *) malloc (1); </li></ul></ul><ul><ul><li>scanf (&quot;%d&quot;, p); </li></ul></ul><ul><ul><li>*p = *p + 142; </li></ul></ul><ul><ul><li>printf (&quot;%d&quot;, *p); </li></ul></ul><ul><ul><li>free (p); </li></ul></ul><ul><li>2-Faça a alocação de um vector, durante a execução de um programa, com n elementos inteiros (n é dado pelo utilizador) </li></ul>int *v; int n, i; scanf (&quot;%d&quot;, &n); v = (int *) malloc (n * sizeof(int)); for (i = 0; i < n; ++i) v[i] = i; . . . free (v);
  10. 10. Ajuste de memória dinâmica <ul><li>É possível alterar o tamanho do bloco de memória reservado, utilizando a função realloc() . Esta função salvaguarda os valores anteriormente digitados em memória, até ao limite do novo tamanho (especialmente importante quando se reduz o tamanho do bloco de memória). O seguinte exemplo ilustra a forma de utilização desta função. </li></ul>
  11. 11. Ajuste de memória dinâmica <ul><li>int *a; </li></ul><ul><li>a = (int *) malloc( 10 * sizeof(int) ); </li></ul><ul><li>(...) </li></ul><ul><li>a = (int *) realloc( a, 23 * sizeof(int) ); </li></ul><ul><li>(...) </li></ul><ul><li>free(a); </li></ul><ul><li>A chamada da função realloc() recebe como argumentos um apontador para o bloco de memória previamente reservado com uma função malloc() de forma a saber qual a porção de memória a ser redimensionada, e o novo tamanho absoluto para o bloco de memória. </li></ul>
  12. 12. Alocação Dinâmica de Memória <ul><li>void * calloc(size_t n, size_t size); </li></ul><ul><li>/* </li></ul><ul><li>calloc retorna um ponteiro para um array com n </li></ul><ul><li> elementos de tamanho size cada um ou NULL se não </li></ul><ul><li> houver memória disponível. Os elementos são </li></ul><ul><li> iniciados em zero </li></ul><ul><li>*/ </li></ul><ul><li>o ponteiro retornado por malloc e calloc deve ser convertido para o tipo de ponteiro que invoca a função: </li></ul>
  13. 13. Alocação Dinâmica de Memória <ul><li>int *ai = ( int *) calloc (n, sizeof( int )); </li></ul><ul><li>/* aloca espaço para um array de n inteiros */ </li></ul><ul><li>toda memória não mais utilizada deve ser liberada através da função free() : </li></ul><ul><li>free(ai); /* libera todo o array */ </li></ul><ul><li>free(pi); /* libera o inteiro alocado */ </li></ul>
  14. 14. Exercícios <ul><li>1- Pretende-se que faça a alocação de espaço em memória para 10 inteiros. Deverá imprimir os seus respectivos endereço de memórias e o seu conteúdo. </li></ul><ul><li>2- Leia uma sequência de 10 números to teclado usando apontadores em lugar de índices. Usando a mesma técnica (apontadores) determine o maior e o menor valor. Reserve memória dinâmica em vez de declarar o vector de uma forma estática. </li></ul><ul><li>3- Ler uma sequência de números do teclado (sequência terminada em zero ).Escreva no ecrã os números que estão acima da média. Utilize um vector dinâmico para armazenar os números. </li></ul>
  15. 15. Resolução Nº 1 1- Pretende-se que faça a alocação de espaço em memória para 10 inteiros. Deverá imprimir os seus respectivos endereço de memórias e o seu conteúdo. int *dados,i;int *p; void main() { clrscr(); dados=(int *)malloc(5*sizeof(int)); if (dados==NULL) { printf (&quot;A alocação não correu bem!!&quot;); exit(1); } p=dados; for (i=0;i<5;i++) { printf(&quot;Digite os numeros&quot;); scanf(&quot;%d&quot;,dados+i);//guarda valores am mem¢ria } for (i=0;i<5;i++) { printf(&quot;Tem o valor %d e est  no endere‡o %d &quot;, *(dados+i),p); //endere‡o de mem¢ria p++; } getch(); }
  16. 16. Resolução Nº 2 <ul><li>Leia uma sequência de 10 números to teclado usando apontadores em lugar de índices. Usando a mesma técnica (apontadores) determine o maior e o menor valor. Reserve memória dinâmica em vez de declarar o vector de uma forma estática. </li></ul><ul><li>#include <stdio.h> </li></ul><ul><li>#include <stdlib.h> </li></ul><ul><li>void main() </li></ul><ul><li>{ int *v, *min, *max; int i, soma = 0; float media; </li></ul><ul><li>/* v passa a apontar para um bloco de memória com capacidade para 10 inteiros */ </li></ul><ul><li>v = (int *) malloc(10 * sizeof(int)); </li></ul><ul><li>for(i = 0; i < 10; i++) </li></ul><ul><li>{ printf(&quot;Insira um número: &quot;); </li></ul><ul><li>scanf(&quot;%d&quot;, v+i); </li></ul><ul><li>} /* min e max passam a apontar para o primeiro valor do vector */ </li></ul><ul><li>min = v; </li></ul><ul><li>max = v; </li></ul><ul><li>for(i = 0; i < 10; i++) </li></ul><ul><li>{ if ( *(v+i) > *max ) </li></ul><ul><li>max = v+i; </li></ul><ul><li>else if ( *(v+i) < *min ) </li></ul><ul><li>min = v+i; </li></ul><ul><li>} </li></ul><ul><li>printf(&quot;O menor número inserido: %d &quot;, *min); </li></ul><ul><li>printf(&quot;O maior número inserido: %d &quot;, *max); </li></ul><ul><li>free(v); </li></ul><ul><li>} </li></ul>
  17. 17. Resolução Nº 3 <ul><li>Ler uma sequência de números do teclado (sequência terminada em zero ).Escreva no ecrã os números que estão acima da média. Utilize um vector dinâmico para armazenar os números. </li></ul>#include <stdio.h> #include <stdlib.h> void main() { int *v; int soma, i, num, c; float media; /* Esta operação é necessária para utilizar posteriormente a função realloc() */ v = (int *) malloc( sizeof(int) ); /* São inicializadas as variáveis soma e contador de números inseridos */ soma = 0; i = 0; /* O primeiro número é inserido antes do ciclo while para verificar se é zero (para a acabar) */ printf(&quot;Insira um número (zero para acabar): &quot;); scanf(&quot;%d&quot;, &num); while( num ) /* O ciclo é executado enquanto num não é zero */ { i++; v = (int *) realloc(v, i*sizeof(int)); *(v+i-1) = num; /* O vector começa na posição zero pelo que i anda avançado um valor */ soma += num; /* É efectuado o somatório dos números inseridos */ /* É inserido um novo número para verificar no início do próximo ciclo */ printf(&quot;Insira um número (zero para acabar): &quot;); scanf(&quot;%d&quot;, &num); } /* O cast (float) força as operações a serem realizadas no domínio dos float */ /* que de outra forma seria nos int (soma e i são ambos inteiros) */ media = (float) soma / i; for(c = 0; c < i; c++) if ( *(v+c) > media ) printf(&quot;O valor %d está acima da média. &quot;, *(v+i)); }

×