ED_I_Un3_Aloc_v4
19 pág.

ED_I_Un3_Aloc_v4


DisciplinaAlgoritmos e Estrutura de Dados I709 materiais7.908 seguidores
Pré-visualização2 páginas
Ciência da Computação 
Tecnologia em Análise e Desenvolvimento de 
Sistemas 
Estrutura de Dados I 
INF1014 - CCB1044 
Alocação Dinâmica de Memória 
SUMÁRIO 
\u2022 Conceito de Alocação Dinâmica 
\u2022 Alocação Dinâmica x Alocação Estática 
\u2022 Funções para Alocação de Memória 
\u2022 Vetores Alocados Dinamicamente 
\u2022 Matrizes Alocadas Dinamicamente 
\u2022 Estruturas Alocadas Dinamicamente 
 
 
 
Alocação Dinâmica de Memória 
\u2022 Conceito de Alocação Dinâmica 
\u2013 é o processo pelo qual um programa pode solicitar e utilizar um bloco 
de memória de tamanho arbitrário, durante sua execução. 
\u2013 é utilizada para que um programa em C utilize apenas a memória 
necessária para sua execução, sem desperdícios de memória. 
\u2022 um exemplo de desperdício de memória é quando um vetor de 1000 
posições é declarado quando não se sabe, de fato, se as 1000 posições 
serão necessárias 
\u2013 a alocação dinâmica de memória deve ser utilizada quando não se 
sabe quanto espaço de memória será necessário para o 
armazenamento de algum ou alguns valores. 
\u2013 existem funções em C próprias para fazer o "pedido" de memória. 
\u2013 um pedido de alocação será recusado se a memória estiver cheia. 
Alocação Dinâmica de Memória 
\u2022 Alocação Dinâmica x Alocação Estática 
\u2013 alocação estática 
\u2022 usa variáveis locais e globais, simples ou em forma 
de arranjo 
\u2022 exige que o programador saiba, de antemão, o 
espaço necessário 
\u2022 variáveis globais ou locais estáticas ocupam um 
espaço fixo durante toda a execução do programa 
\u2022 variáveis locais ocupam espaço na pilha, cujo 
tamanho varia conforme a necessidade (funções 
recursivas demandam mais memória de pilha) 
\u2013 alocação dinâmica 
\u2022 o espaço é ocupado no heap, que também varia 
conforme a necessidade 
 
memória do sistema 
variáveis globais 
programa 
memória livre 
(heap) 
pilha 
em casos extremos a pilha pode colidir com 
o heap e ocorrerá uma falha 
Alocação Dinâmica de Memória 
\u2022 Alocação Dinâmica x Alocação Estática 
\u2013 alocação estática 
\u2022 uso de variáveis globais (ou estáticas): 
\u2013 espaço reservado existe enquanto o programa estiver sendo 
executado 
\u2022 uso de variáveis locais: 
\u2013 espaço existe apenas enquanto a função que declarou a variável 
está sendo executada 
\u2013 liberado para outros usos quando a execução da função termina 
\u2013 alocação dinâmica 
\u2022 espaço de memória é requisitado em tempo de execução e permanece 
reservado até que seja explicitamente liberado 
\u2022 depois de liberado, espaço estará disponibilizado para outros usos e não 
pode mais ser acessado 
\u2022 espaço alocado e não liberado explicitamente, será automaticamente 
liberado ao final da execução 
Alocação Dinâmica de Memória 
\u2022 Funções para Alocação de Memória 
\u2013 Função malloc (stdio.h) 
\u2022 função para solicitar a alocação de um dado número de bytes 
 
 
\u2022 retorna um ponteiro genérico para o endereço inicial da área de memória 
alocada, se houver espaço livre: 
\u2013 ponteiro genérico é representado por void* 
\u2013 ponteiro é convertido automaticamente para o tipo apropriado 
\u2013 ponteiro pode ser convertido explicitamente 
\u2022 retorna um endereço nulo, se não houver espaço livre: 
\u2013 representado pelo símbolo NULL 
número_de_bytes: número de bytes que se quer alocar 
(o tipo size_t é um inteiro sem sinal definido em stdio.h) 
void* malloc(size_t número_de_bytes) 
como o heap não é infinito, após a alocação é necessário testar o 
valor devolvido por malloc() 
(ex_14) 
(ex_15) 
Alocação Dinâmica de Memória 
\u2022 Funções para Alocação de Memória 
\u2013 Função malloc (stdio.h) 
\u2022 Exemplos (serão vistos em detalhe mais adiante) 
\u2013 vetor de 10 inteiros 
 
 
 
 
\u2013 matriz bidimensional de inteiros 
 
 
 
 
 
 
// equivalente a int aVetor[10] 
int *aVetor; 
aVetor = (int *) malloc(10 * sizeof(int)); 
 
if (aVetor == NULL) 
 printf (\u201cMemória insuficiente\u201d); 
 
// equivalente a int aMatriz[2][3] 
int **amatriz; 
aMatriz = (int**) malloc(2 * sizeof(int*)); //linhas 
for( i=0; i<2 ; i++ ) 
{ 
aMatriz[i] = (int*) malloc(3 * sizeof(int)); //colunas 
} 
Alocação Dinâmica de Memória 
\u2022 Funções para Alocação de Memória 
\u2013 Função free (stdio.h) 
\u2022 função que libera bloco de memória alocado previamente 
 
 
 
\u2022 quando não se deseja mais uma área alocada, deve-se liberá-la através 
da função free. 
 
void free(void *nome) 
nome: nome do ponteiro para a memória alocada por malloc() 
é importante nunca usar free() com um argumento inválido, pois, 
isso destruiria a lista de memória livre 
(ex_16) 
Alocação Dinâmica de Memória 
\u2022 Funções para Alocação de Memória 
\u2013 Função calloc (stdio.h) 
\u2022 função para solicitar a alocação de uma dada quantidade de objetos de 
um determinado tamanho 
 
 
 
 
 
 
 
void* calloc (size_t quantidade, size_t tamanho) 
a única diferença entre malloc e calloc é que a última função, além de 
alocar o espaço, também inicializa o mesmo com zeros 
(ex_17) 
quantidade : quantidade de objetos que se quer alocar 
tamanho : número de bytes do objeto que se quer alocar 
Alocação Dinâmica de Memória 
\u2022 Funções para Alocação de Memória 
\u2013 Função realloc (stdio.h) 
\u2022 função que permite que uma área previamente alocada seja aumentada 
ou diminuída 
 
 
 
\u2022 o conteúdo do objeto será mantido até um tamanho igual ao menor dos 
dois tamanhos, novo e antigo 
\u2022 se o novo tamanho requerer movimento, o espaço reservado 
anteriormente será liberado 
\u2022 se o novo tamanho for maior, o conteúdo da porção de memória 
reservada a mais ficará com um valor sem especificação 
\u2022 se o tamanho número_de_bytes for igual a 0 e nome não for um 
ponteiro nulo, o objeto previamente reservado será liberado. 
 
void* realloc(void *nome, size_t número_de_bytes) 
(ex_18) 
nome: nome do ponteiro para a área de memória alocada que se quer reajustar 
número_de_bytes: novo número de bytes que se quer que a dada área ocupe 
Alocação Dinâmica de Memória 
\u2022 Vetores Alocados Dinamicamente 
\u2013 vetores de tamanho dinâmico, determinado em tempo de execução 
#include <stdio.h> 
#include <stdlib.h> 
int main(void) 
{ 
int *p; 
int i,k, n; 
printf(&quot;\nDigite a quantidade de números que serão digitados ->&quot;); 
scanf(&quot;%d&quot;, &i); 
p = (int *)(malloc(i*sizeof(int))); 
if (p == NULL ){ 
printf(&quot;\nErro de alocacao de memoria&quot;); 
exit(1); 
} 
for(k=0; k<i; k++){ 
printf(&quot;Digite o numero para o indice %d ->&quot;, k); 
scanf(&quot;%d&quot;, &p[k]); 
} 
for(k=0;k<i;k++){ 
printf(&quot;O numero do indice %d eh %d\n&quot;, k, p[k]); 
} 
 
//continua 
A função malloc reserva 
espaço suficiente para um 
vetor de inteiros. Por ex., 
para 5 elementos, serão 
reservados 20 bytes, 
considerando que cada 
inteiro ocupa 4 bytes na 
memória. 
Alocação Dinâmica de Memória 
\u2022 Vetores Alocados Dinamicamente 
\u2013 vetores de tamanho dinâmico, determinado em tempo de execução 
printf(&quot;\nDigite quantos elementos quer adicionar ao vetor ->&quot;); 
scanf(&quot;%d&quot;, &n) 
p = (int *)(realloc(p,(i+n)*sizeof(int))); 
if( p == NULL ){ 
printf(&quot;\nErro de re-alocacao de memoria&quot;); 
exit(1); 
} 
for(;k<(n+i);k++){ 
printf(&quot;Digite o numero para o indice %d ->&quot;, k); 
scanf(&quot;%d&quot;, &p[k]); 
} 
for( k=0;k<(i+n);k++) 
{ 
printf(&quot;O numero do indice %d eh %d\n&quot;, k, p[k]); 
} 
free(p); 
return 0; 
} 
 
A função realloc aumenta ou 
diminui o tamanho do vetor 
dinamicamente. Ela recebe o 
ponteiro para o vetor 
anterior e retorna o novo 
espaço alocado. 
Alocação Dinâmica de Memória 
\u2022 Vetores Alocados Dinamicamente 
\u2013 o uso de vetores locais a funções requer cuidado 
\u2013 exemplo 
\u2022 produto vetorial de dois vetores