UDESC - SBS
Departamento de Sistemas de Informação
LPG - I: Alocação Dinâmica
de Memória - Ponteiros
Prof. Flavio Marcello Strelow
[email protected]
Memória Disponível no Computador
PROGRAMA
ÁREA LIVRE
Memória livre, gerenciada
pelo sistema operacional
Código executável:
- instruções (compilador)
- armazenamento do dados (estrutura dos dados)
Alocação de Memória - Estática
 Estática



Quantidade total de memória utilizada pelos
dados é previamente conhecida e definida de
modo imutável, no próprio código-fonte do
programa.
Durante toda a execução, a quantidade de
memória utilizada pelo programa não varia.
Lista de variáveis declaradas.
Alocação de Memória - Estática
 Implementação simples: vetores (array)
 Vantagem:
 acesso indexado (vi)- todos os elementos da
estrutura são igualmente acessíveis
 Desvantagens:
 tamanho fixo (#define TAM 1000)
 tempo de compilação
 alocados em memória de forma estática
Alocação de Memória - Estática
 Ao se determinar o máximo de elementos
que o vetor irá conter, pode-se ocorrer um
dos seguintes casos:


Subdimensionamento: haverá mais
elementos a serem armazenados do que o
vetor é capaz de conter;
Superdimensionamento: na maior parte do
tempo, somente uma pequena porção do
vetor será realmente utilizada.
Alocação de Memória - Dinâmica
 Dinâmica


Quanto o programa é capaz de criar novas
variáveis enquanto está sendo executado.
Alocação de memória para componentes
individuais no instante em que eles começam
a existir durante a execução do programa.
Alocação Estática
x
Alocação Dinâmica
Alocação Dinâmica
 Implementação eficiente: ponteiros ou
apontadores
 Vantagens:



tamanho variável
tempo de execução
alocados em memória de forma dinâmica
 Desvantagem, ou restrição:
 capacidade da memória, acesso seqüencial
Alocação de Memória - Ponteiros
 No padrão C ANSI que define as funções
para a alocação dinâmica (alocar e liberar
blocos de memória em tempo de execução)
estão disponíveis na biblioteca stdlib.h.


malloc: alocar memória.
free: liberar áreas da memória ocupadas.
 Precisaremos tambem do:

sizeof: retorna o tamanho de uma variável.
Operador sizeof()
sizeof
sizeof(<expressão> | <tipo>)
 Retorna o número de bytes necessários para
armazenar um objeto na memória, ou seja,
saber o tamanho de tipos .
 O objeto pode ser um vetor, estrutura(struct)
ou uma expressão como 5+9 ou 2.5*3.
Alocação de Memória - malloc
malloc
void* malloc(tamanho_a_alocar);
 Recebe o número de bytes a alocar.
 Retorna um apontador void para a base da região
contígua alocada na memória ou NULL se não for
possível alocá-la.
 É responsabilidade do programador liberar a
memória alocada dinamicamente com free.
 Produz erros estranhos quando usada para liberar
um espaço que já foi liberado.
Alocação de Memória - Exemplos
 Alocação de memória para um
inteiro:
int *p = malloc( 3 * sizeof(int));
 Alocação de memória para um array
de n reais:
float *p = malloc(n * sizeof(float));
Representação Interna da Variável do Tipo
Ponteiro:
aloca a variável estaticamente
void main() {
int *p; I
aloca a variável dinamicamente
p = (int *) malloc(sizeof(int)); II
*p = 10; III
...
IV
free(p);
}
memória usada
pelo programa
endereço
1FFA
Lixo
10
1FFA
p: Lixo
memória livre
no sistema
Entendendo o código:
I - int *p;
A variável p é um ponteiro para um número inteiro, ou seja, “aponta”
para um endereço de memória que será “alocado” para armazenar um
número inteiro (2 bytes)
II - p = (int *) malloc(sizeof(int));
Solicita ao sistema operacional 2 bytes da memória livre e o “endereço
do espaço alocado” é colocado na variável ponteiro p
III - *p = 10;
No endereço apontado por p armazena o número inteiro 10
IV - free(p);
Libera o espaço de memória ocupado cujo endereço está em p
(devolve o recurso ao sistema operacional)
Exemplo
 Faça um programa para ler 10 números reais
e armazene em um vetor alocado
dinamicamente. Depois, imprima os
elementos lidos.
Exemplo
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define TAM 10
int main() {
int *pti, i;
pti= (int *) malloc(sizeof(int) * TAM);
if (pti == NULL) {
/* verifica alocação, (poderia ser  if(!pti)) */
printf("Erro ao alocar memória!\n");
return 1;
/* sai do programa */
}
for (i=0; i<TAM; i++) {
printf("Digite um numero inteiro: ");
scanf("%d", &pti[i]); /* lê e armazena no vetor de endereços */
}
/* Impressao do ponteiro */
for (i=0; i<TAM; i++)
printf("%d", pti[i]);
free(pti); // libera memoria.
return 0;
}
Alocação de Ponteiros
LPG-I
Flavio Marcello
Exercícios
 Faça um programa que aloque uma string de
30 caracteres, armazene uma palavra
digitada pelo usuário nesta string, imprima na
tela e, depois de imprimido, desaloque esta
string.
 Faça um programa que leia 5 strings e
armazene em uma matriz de strings. Cada
string deve ter seu espaço alocado
dinamicamente (considere strings de no
máximo 20 caracteres na leitura).
3) Faça um programa que aloque uma string de 30 caracteres, armazene uma palavra digitada pelo usuário
nesta string, imprima na tela e, depois de imprimido, desaloque esta string.
#include <stdio.h>
#include <stdlib.h>
main()
{
char *string;
/* alocar a string de 30 caracteres */
string= (char *) malloc(sizeof(char) * 30);
if (!string)
/* se alocação falhou (se string for igual a NULL) */
{
printf("Erro ao alocar memória!\n");
return 1;
/* sai do programa */
}
printf("Digite uma palavra: ");
fgets(string, 30, stdin);
printf("A palavra digitada é %s\n", string);
free(string);
/* desaloca a string */
return 0;
}
/*4) Faça um programa que leia 5 strings e armazene em uma matriz de strings.
Cada string deve ter seu espaço alocado dinamicamente
(considere strings de no máximo 20 caracteres). */
#include <stdio.h>
#include <stdlib.h>
main() {
char *mat[5];
int i;
for (i=0; i<5; i++) {
/* aloca espaço para as strings */
mat[i]= (char *) malloc(sizeof(char) * 20);
if (!mat[i]) {
printf("Falha na alocação de memória!\n");
return 1;
}
printf("Digite uma palavra: ");
fgets(mat[i], 20, stdin);
}
/* imprime as strings */
for (i=0; i<5; i++) {
puts(mat[i]);
free(mat[i]); /* desaloca a string */
}
return 0;
/* OBS: Quando um dado é alocado dinamicamente, é importante desalocá-lo antes de
encerrar o programa. Se isso não for feito, a variável continuará ocupando espaço
desnecessariamente após o término da execução do programa. Também é importante
testar se ocorreu algum erro na alocação, para tratá-lo, se houver. */
}
Download

p - Udesc