Escola Secundária c/ 3º CEB da Batalha
Alocação dinâmica de memória
Linguagem C
Composição de Estruturas
struct rectangulo {
struct ponto inicio;
struct ponto fim;
};
struct rectangulo r = { { 10, 20 },
{ 30 , 40 }
};
• Acesso aos dados:
r.inicio.x += 10;
r.inicio.y -= 10;
r
inicio
x: 10
y: 20
fim
x:
y:
30
40
Linguagem C
Ponteiros para Estruturas
Estruturas grandes são passadas como parâmetro
p1
De forma mais eficiente através de ponteiros
x:
y:
10
20
struct ponto *pp;
pp
1002
struct ponto p1 = { 10, 20 };
1002
pp = &p1;
printf(“Ponto P1: (%d %d)\n”, (*pp).x, (*pp).y};
• Aceder com o operador “->”:
printf(“Ponto P1: (%d %d)\n”, pp->x, pp->y};
(*pp).x == pp->x
Linguagem C
Alocação Dinâmica de Memória
• incluir a biblioteca standard do C: stdlib.h
(malloc() e free())
• possibilidade de libertar memória à medida
que deixa de ser precisa
• as funções calloc e malloc permitem alocar
blocos de memória em tempo de execução
número de bytes alocados
void * malloc( size_t n);
/*
retorna um ponteiro void para n bytes de memória
não iniciados. Se não há memória disponível
malloc retorna NULL
*/
Linguagem C
Alocação Dinâmica de Memória
• A função malloc() (memory allocation)
• 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
• A sua utilização é representada no exemplo seguinte:
int *pi;
pi= (int *) malloc (sizeof(int));
/* aloca espaço para um inteiro */
Linguagem C
malloc() – exemplo
Pág.424
float *v;
int n;
printf("Quantos valores? ");
scanf("%d", n);
v = (float *) malloc(n * sizeof(float) );
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.
Linguagem C
malloc()
• 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.
float *v,*paux;
int n;
printf("Quantos valores? ");
scanf("%d", n);
v = (float *) malloc(n * sizeof(float) );
paux=v;
Linguagem C
Libertar memória dinâmica
• A memória é libertada utilizando a função
free()
int *pi;
pi= (int *) malloc (sizeof(int));
• Para libertar a memória:
free(pi);
Linguagem C
Exercícios
1-Diga qual o output do seguinte programa:
int *p;
p = (int *) malloc (sizeof(int));
scanf ("%d", p);
*p = *p + 142;
printf ("%d", *p);
free (p);
ou (int *) malloc (1);
2-Faça a alocação de um vector, durante a
execução de um programa, com n elementos
inteiros (n é dado pelo utilizador)
int *v;
int n, i;
scanf ("%d", &n);
v = (int *) malloc (n * sizeof(int));
for (i = 0; i < n; ++i)
v[i] = i;
. . .
free (v);
Linguagem C
Ajuste de memória dinâmica
• É 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.
Linguagem C
Ajuste de memória dinâmica
int *a;
a = (int *) malloc( 10 * sizeof(int) );
(...)
a = (int *) realloc( a, 23 * sizeof(int) );
(...)
free(a);
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.
Linguagem C
Alocação Dinâmica de Memória
void * calloc(size_t n, size_t size);
/*
calloc retorna um ponteiro para um array com n
elementos de tamanho size cada um ou NULL se não
houver memória disponível. Os elementos são
iniciados em zero
*/
• o ponteiro retornado por malloc e calloc deve ser
convertido para o tipo de ponteiro que invoca a
função:
Linguagem C
Alocação Dinâmica de Memória
int *ai = (int *) calloc (n,
sizeof(int));
/* aloca espaço para um array de n
inteiros */
• toda memória não mais utilizada deve ser
liberada através da função free():
free(ai);
free(pi);
/* libera todo o array */
/* libera o inteiro alocado */
Linguagem C
Exercícios
• 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.
• 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.
• 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.
Linguagem C
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 ("A alocação não correu bem!!");
exit(1);
}
p=dados;
for (i=0;i<5;i++)
{
printf("Digite os numeros");
scanf("%d",dados+i);//guarda valores am mem¢ria
}
for (i=0;i<5;i++)
{
printf("Tem o valor %d e est
no endere‡o %d\n", *(dados+i),p);
//endere‡o de mem¢ria
p++;
}
getch();
}
Linguagem C
Resolução Nº 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.
#include <stdio.h>
#include <stdlib.h>
void main()
{ int *v, *min, *max; int i, soma = 0; float media;
/* v passa a apontar para um bloco de memória com capacidade para 10 inteiros */
v = (int *) malloc(10 * sizeof(int));
for(i = 0; i < 10; i++)
{ printf("Insira um número: ");
scanf("%d", v+i);
}
/* min e max passam a apontar para o primeiro valor do vector */
min = v;
max = v;
for(i = 0; i < 10; i++)
{ if ( *(v+i) > *max )
max = v+i;
else if ( *(v+i) < *min )
min = v+i;
}
printf("O menor número inserido: %d\n", *min);
printf("O maior número inserido: %d\n", *max);
free(v);
}
Linguagem C
Resolução Nº 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.
#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("Insira um número (zero para acabar): ");
scanf("%d", &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("Insira um número (zero para acabar): ");
scanf("%d", &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("O valor %d está acima da média.\n", *(v+i));
}
Linguagem C
Download

Malloc