Buscar

Aula 11: Alocação Dinâmica

Prévia do material em texto

LINGUAGEM C:
ALOCAÇÃO DINÂMICA
Prof. André Backes
DEFINIÇÃO
 Sempre que escrevemos um programa, é preciso 
reservar espaço para as informações que serão 
processadas.
 Para isso utilizamos as variáveis
 Uma variável é uma posição de memória que armazena 
uma informação que pode ser modificada pelo 
programa.
 Ela deve ser definida antes de ser usada.
DEFINIÇÃO
 Infelizmente, nem sempre é possível saber, em 
tempo de execução, o quanto de memória um 
programa irá precisar.
 Exemplo
 Faça um programa para cadastrar o preço de N 
produtos, em que N é um valor informado pelo usuário
Errado! Não sabemos o 
valor de N
Funciona, mas não é o 
mais indicado
DEFINIÇÃO
 A alocação dinâmica permite ao programador criar 
“variáveis” em tempo de execução, ou seja, alocar 
memória para novas variáveis quando o programa 
está sendo executado, e não apenas quando se 
está escrevendo o programa.
 Quantidade de memória é alocada sob demanda, ou 
seja, quando o programa precisa
 Menos desperdício de memória
 Espaço é reservado até liberação explícita
 Depois de liberado, estará disponibilizado para outros usos e 
não pode mais ser acessado
 Espaço alocado e não liberado explicitamente é 
automaticamente liberado ao final da execução
ALOCANDO MEMÓRIA
Alocando 5 
posições de 
memória em int *p
Memória
posição variável conteúdo
119
120
121 int *p NULL
122
123
124
125
126
127
128
Memória
posição variável conteúdo
119
120
121 int *p 123
122
123 p[0] 11
124 p[1] 25
125 p[2] 32
126 p[3] 44
127 p[4] 52
128
ALOCAÇÃO DINÂMICA
 A linguagem C ANSI usa apenas 4 funções para o 
sistema de alocação dinâmica, disponíveis na 
stdlib.h:
 malloc
 calloc
 realloc
 free
ALOCAÇÃO DINÂMICA - MALLOC
 malloc
 A função malloc() serve para alocar memória e tem o 
seguinte protótipo:
 Funcionalidade
 Dado o número de bytes que queremos alocar (num), 
ela aloca na memória e retorna um ponteiro void* para 
o primeiro byte alocado.
ALOCAÇÃO DINÂMICA - MALLOC
 O ponteiro void* pode ser atribuído a qualquer tipo 
de ponteiro via type cast. Se não houver memória 
suficiente para alocar a memória requisitada a 
função malloc() retorna um ponteiro nulo.
ALOCAÇÃO DINÂMICA - MALLOC
 Alocar 1000 bytes de memória livre.
 Alocar espaço para 50 inteiros:
ALOCAÇÃO DINÂMICA - MALLOC
 Operador sizeof()
 Retorna o número de bytes de um dado tipo de dado. 
Ex.: int, float, char, struct...
ALOCAÇÃO DINÂMICA - MALLOC
 Operador sizeof()
 No exemplo anterior, 
p = (int *) malloc(50*sizeof(int));
 sizeof(int) retorna 4 
 número de bytes do tipo int na memória
 Portanto, são alocados 200 bytes (50 * 4)
 200 bytes = 50 posições do tipo int na memória
ALOCAÇÃO DINÂMICA - MALLOC
 Se não houver memória suficiente para alocar a 
memória requisitada, a função malloc() retorna um 
ponteiro nulo
ALOCAÇÃO DINÂMICA - CALLOC
 calloc
 A função calloc() também serve para alocar memória, 
mas possui um protótipo um pouco diferente:
 Funcionalidade
 Basicamente, a função calloc() faz o mesmo que a 
função malloc(). A diferença é que agora passamos a 
quantidade de posições a serem alocadas e o tamanho 
do tipo de dado alocado como parâmetros distintos da 
função.
ALOCAÇÃO DINÂMICA - CALLOC
 Exemplo da função calloc
ALOCAÇÃO DINÂMICA - REALLOC
 realloc
 A função realloc() serve para realocar memória e tem o 
seguinte protótipo:
 Funcionalidade
 A função modifica o tamanho da memória previamente alocada 
e apontada por *ptr para aquele especificado por num. 
 O valor de num pode ser maior ou menor que o original.
ALOCAÇÃO DINÂMICA - REALLOC
 realloc
 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 DINÂMICA - REALLOC
 Observações sobre realloc()
 Se *ptr for nulo, aloca num bytes e devolve um 
ponteiro (igual malloc); 
 se num é zero, a memória apontada por *ptr é liberada 
(igual free). 
 Se não houver memória suficiente para a alocação, um 
ponteiro nulo é devolvido e o bloco original é deixado 
inalterado.
ALOCAÇÃO DINÂMICA - FREE
 free
 Diferente das variáveis definidas durante a escrita do 
programa, as variáveis alocadas dinamicamente não 
são liberadas automaticamente pelo programa.
 Quando alocamos memória dinamicamente é 
necessário que nós a liberemos quando ela não for 
mais necessária. 
 Para isto existe a função free() cujo protótipo é: 
ALOCAÇÃO DINÂMICA - FREE
 Assim, para liberar a memória, basta passar como 
parâmetro para a função free() o ponteiro que 
aponta para o início da memória a ser desalocada.
 Como o programa sabe quantos bytes devem ser 
liberados? 
 Quando se aloca a memória, o programa guarda o 
número de bytes alocados numa "tabela de alocação" 
interna.
ALOCAÇÃO DINÂMICA - FREE
 Exemplo da função free()
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
MATERIAL COMPLEMENTAR
 Vídeo Aulas
 Aula 60: Alocação Dinâmica pt.1 – Introdução
 Aula 61: Alocação Dinâmica pt.2 – Sizeof
 Aula 62: Alocação Dinâmica pt.3 – Malloc
 Aula 63: Alocação Dinâmica pt.4 – Calloc
 Aula 64: Alocação Dinâmica pt.5 – Realloc
 Aula 65: Alocação Dinâmica pt.6 – Alocação de Matrizes

Outros materiais