Você está na página 1de 37

Algoritmos e

Estruturas de
Dados I
Aula 2: Alocação Dinâmica de Memória
Área de memória onde dados são
armazenados:

Variável = variável estática (lista de variáveis)


endereço • existência prevista no código do programa (tempo de
compilação)
de • quantidade de memória utilizada pelo programa não varia

memória
variável dinâmica

passam a existir durante a execução do


programa 2
Memória Disponível no Computador

PROGRAMA ÁREA LIVRE

Memória livre, gerenciada


pelo sistema operacional

Código executável:
- instruções (compilador)
- armazenamento dos dados (estrutura dos dados)
#include <stdio.h> Topo da Memória
StackPointer
char *a, *b;
Início da Pilha

int func_A () {
int local1, local2;

}

void func_B () { HeapPointer


int localA, localB; Início da Área
localA = func_A(); Alocável
localB = func_A(); aa
} bb

Programa
Variáveis estáticas
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; Constantes
"Essa
"Essaaula
"Será
aulaéé......
"Serámesmo..
b = "Será mesmo?" mesmo..

func_B(); Sistema
SistemaOperacional
Operacional
}
StackPointer Topo da Memória

#include <stdio.h> Início da Pilha


char *a, *b;

int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
StackPointer Topo da Memória

#include <stdio.h> Início da Pilha


char *a, *b;

int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; StackPointer localB

Início da Pilha
int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; StackPointer localB

Início da Pilha
int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; localB
&func_B-#2
int func_A () { local1
StackPointer local2
int local1, local2;
… Início da Pilha
}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; localB
&func_B-#2
int func_A () { local1
StackPointer local2
int local1, local2;
… Início da Pilha
}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; StackPointer localB
Início da Pilha
int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; localB
&func_B-#3
int func_A () { local1
StackPointer local2
int local1, local2;
… Início da Pilha
}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; localB
&func_B-#3
int func_A () { local1
StackPointer local2
int local1, local2;
… Início da Pilha
}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Topo da Memória
&main-#3
#include <stdio.h> localA
char *a, *b; StackPointer localB
Início da Pilha
int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
StackPointer Topo da Memória

#include <stdio.h> Início da Pilha


char *a, *b;

int func_A () {
int local1, local2;

}
HeapPointer
void func_B () {
Início da Área
int localA, localB;
Alocável
localA = func_A();
localB = func_A(); aa
Variáveis estáticas bb
}
10010101...
10010101...
main () { Código objeto
a = "Essa aula é legal"; "Essa
"Essaaula
aulaé é......
b = "Será mesmo?" Constantes "Será mesmo..
"Será mesmo..
func_B();
} Sistema
SistemaOperacional
Operacional

Base da Memória
Alocação Dinâmica
• Uso da memória:
• alocação dinâmica de memória:
Código do programa

memória
estática
• usa a memória livre
Variáveis globais e
• se o espaço de memória livre for menor que o
espaço requisitado, Variáveis estáticas
a alocação não é feita e Variáveis alocadas
o programa pode prever
tratamento de erro dinamicamente
• pilha de execução:

memória
estática
• utilizada para alocar memória quando ocorre Memória livre
chamada de função:
• sistema reserva o espaço
para as variáveis locais da função Variáveis locais
• quando a função termina, (Pilha de execução)
espaço é liberado (desempilhado)
• se a pilha tentar crescer mais do que o espaço
disponível existente, 16
programa é abortado com erro
Alocação Dinâmica
Usada sempre que não se sabe exatamente quanto de
memória será usado para uma determinada tarefa.

Assim, reserva-se espaço da memória disponível (HEAP) à


medida que mais memória torna-se necessária.

Também pode-se liberar posições de memória quando não


forem mais necessárias.

É como se pudéssemos definir um VETOR com o seu tamanho


sendo alterado à medida que fosse necessário. 17
Alocação Dinâmica X Alocação Estática
Alocação Dinâmica Alocação Estática
• Quantidade total de memória • Quantidade total de memória
definida em tempo de execução  previamente conhecida  IMUTÁVEL
VARIÁVEL • Implementação simples: vetores
• Implementação eficiente: ponteiros • Vantagem
• Vantagem • Acesso indexado  todos os elementos
da estrutura são igualmente acessíveis
• Tamanho variável
• Tempo de execução • Desvantagem
• Alocados na memória de forma • Tamanho fixo ( sub- ou super-
dinâmica dimensionamento)
• Tempo de compilação
• Desvantagem
• Alocados na memória de forma estática
• Capacidade da memória
Variáveis dinâmicas -
ponteiros

• Armazenam endereços
de memória
• Não armazenam o
valor
• Necessitam ter o
espaço de memória
para o valor alocados
Exemplos
Para acessar o conteúdo de um
ponteiro usamos:
• *nome_do_ponteiro

O operador * determina o conteúdo


Ponteiros de um endereço.

A um ponteiro pode ser atribuído o


valor nulo (constante NULL da
biblioteca stdlib.h)
• Um ponteiro com valor NULL não
aponta para lugar nenhum. 21
• Na linguagem C os comandos
principais para trabalhar com ponteiros
são:
Variáveis • malloc()
dinâmicas - • realloc()
ponteiros • calloc()
• free()
Malloc()

• Recebe como parâmetro a


quantidade de bytes.
• A função pega o número de
bytes que queremos alocar
(num), aloca na memória.
• Retorna um ponteiro genérico
(void *) para o inicio da
memória alocada
Malloc()
Função que retorna
o tamanho em bytes
de um tipo
• O ponteiro void * pode
ser atribuído a qualquer
tipo de ponteiro.
• Retorna um ponteiro
nulo quando não é
possível alocar a
memória
Tratamento de
erro após
chamada a malloc

• Imprime
mensagem de
erro
• Encerra o
programa
Calloc

• Também serve para alocar


memória, mas possui uma
chamada um pouco diferente.
• A função aloca uma quantidade
de memória igual a num * size,
isto é, aloca memória suficiente
para uma matriz de num
objetos de tamanho size.
• Em relação a malloc, calloc tem
uma diferença: calloc inicializa
o espaço alocado com 0
Calloc
Realloc

• Serve para realocar


memória e tem o protótipo
da imagem.
• A função modifica o
tamanho da memória
previamente alocada
apontada por *ptr para
aquele especificado por
num.
• O valor de num pode ser
maior ou menor que o
original.
Realloc
• Realloc() devolve um ponteiro
para a nova alocação, pois
pode precisar mover o bloco
para aumentar seu tamanho.
• Nesse caso o conteúdo
do bloco antigo é copiado
no novo bloco.
• Se ptr for nulo, aloca num
bytes e devolve um
ponteiro; se num é zero, a
memória apontada por
ptr é liberada.
• Se não houver memória
suficiente para a alocação, um
ponteiro nulo é devolvido e o
bloco original é deixado
inalterado
Free

• 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 está na
imagem.
Free
• Basta então passar para free() o ponteiro que
aponta para o início da memória alocada.
• Mas você pode se perguntar: como é que o
programa vai saber quantos bytes devem ser
liberados?
• Ele sabe pois quando você alocou a memória, ele
guardou o número de bytes alocados numa
"tabela de alocação" interna.
31
• Utiliza-se o operador unário *
• int *ap_int;
• char *ap_char;
Declaração de
Ponteiros
• float *ap_float;
• double *ap_double;
• int *ap1, *ap_2, *ap_3;
• int *ap1, int1, int2;
32
Ponteiros
para
Estruturas
Ponteiros
para
estruturas
1. Crie uma estrutura que represente uma pessoa,
contendo nome, data de nascimento e CPF. Crie
uma variável que é um ponteiro para esta
estrutura (no programa principal). Depois crie uma
função que receba este ponteiro e preencha os
Exercícios dados da estrutura e também uma função que receba
Práticos este ponteiro e imprima os dados da estrutura. Na
função principal pergunte ao usuário o número n de
pessoas a serem representadas e utilize "n" para
alocar a memória para seu ponteiro de estrutura.
Ao final das chamadas das funções, não esqueça
de liberar a memória alocada!

35
2. Faça um programa que leia do teclado os dados de n
alunos. Utilize vetor de registro para armazenar os
dados de cada aluno. Esse vetor deve ser obtido
através de uma alocação dinâmica, a partir do valor
de n informado pelo usuário. O registro contém
Exercícios NumMat (tipo inteiro) e um vetor de reais de
Práticos tamanho 3 chamado NOTAS. Ao final, imprima seus
dados, seguido da média das três notas de cada aluno
e sua situação (aprovado – média>=7, reprovado –
média < 3, exame final – média entre 3 e 6);

36
Extra  executando C no python

Você também pode gostar