Gerenciamento de Área de Alocação Dinâmica (Listas Encadeadas)
Publicado por Danilo Azevedo (última atualização em 23/07/2014)
[ Hits: 3.240 ]
Download gereciador_de_memoria.zip
Implementação de um sistema de gerenciamento de trechos livres e ocupados de uma área de alocação dinâmica de memória.
A área de alocação será chamada de buffer. O buffer será formado por N slots. Cada slot tem um índice, que varia de 0 a N - 1. Inicialmente o buffer será considerado vazio. O programa receberá solicitações de operações sobre o buffer, como solicitações para alocar um conjunto de slots (contíguos), desalocar os slots alocados em uma solicitação o anterior ou solicitar informações sobre área de alocação. O índice do slot onde uma área alocada ou livre inicia será chamado o índice inicial daquela área.
O tamanho N do buffer (numero de slots) deverá ser uma constante no programa. Inicialmente deve-se atribuir o valor 20 a esta constante. Posteriormente, no entanto, o valor desta constante poderá ser alterado.
Para a implementação deste exercício, deve-se utilizar listas implementadas com apontadores.
Os formatos de entrada e saída do programa estão indicados nas seções a seguir. O programa deve ler da entrada padrão e escrever na saída padrão.
Segue no anexo informações de como usar o código e o programa.
/* UNIVERSIDADE FEDERAL DA BAHIA
CURSO: BACHARELADO EM CIENCIA DA COMPUTACAO
DISCIPLINA: ESTRUTURA DE DADOS E ALGORITMOS
ALUNO: DANILO AZEVEDO SANTOS - MATRICULA:209200256
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//#include <conio.h>
typedef struct blocoLista{
int id;
int inicio;
int tamanho;
//char id2;
struct blocoLista *prox, *ant;
}blocoLista, *Lista;
typedef struct identificador{
int chave;
struct identificador *prox;
}identificador, *ListaInt;
#define MAX 20
#define vazio -1
/* DECLARACOES DE FUNCOES */
bool consultaListaId(ListaInt *i, int x);
bool criaLista(ListaInt *i, int x);
bool iniciarListas(ListaInt *i, Lista *l);
bool insere_Lista(Lista *l, int id, int tamanho);
Lista areasLivre(Lista *l);
Lista areasOcupadas(Lista *l);
Lista buscaBloco(Lista *l, int id);
Lista consultaBestFit(Lista *l, int tam);
Lista consultaFirstFit(Lista *l, int tam);
Lista consultaLista(Lista *l, int id);
Lista consultaWorstFit(Lista *l, int tam);
Lista defragmentacao(Lista *l);
Lista retirar_lista(Lista *l, int x);
bool retira_desalocacao(Lista *l, int id);
int verEspaco(Lista *l);
void corrigirPosicao(Lista *l);
void experimento(Lista *l, ListaInt *i, int num);
void inicializar(Lista *l);
Lista funcao_teste(Lista *l);
/* */
int main (){
int i, j, tam_entrada, id, tam; char operacao, id_aloc[30], tam_aloc[5], id_area, entrada[30];
Lista lista, aux; ListaInt listaint;
iniciarListas(&listaint,&lista);
inicializar(&lista);
while(1){ //LOOP DO ESCOPO DE REPETICAO P/ SAIR ENTRE 'e'
aux=NULL;
fflush(stdin);
gets(entrada);
operacao = entrada[0];//IDENTIFICADOR DE OPERACAO
{//if's
if(operacao == 'a'){ // VERIFICANDO O TIPO DE ENTRADA
id = 0; tam = 0;
i = 2; j = 0;
while(entrada[i] != ' '){// EXTRAINDO O IDENTIFICADOR DE ALOCACAO
id_aloc[j] = entrada[i];
i++;
j++;
}
id_aloc[j]='{FONTE}';
id = atoi(id_aloc); //CONVERTE ID_ALOC DE CHAR PARA INTEIRO
i = strlen(id_aloc) + 3; // TAMANHO DO IDENTIFICADOR DE ALOCACAO + 2 + 1 - PELO ESPACO
j = 0;
while(entrada[i] != ' '){//EXTRAINDO O TAMANHO DA ALOCACAO
tam_aloc[j] = entrada[i];
i++;
j++;
}
tam_aloc[j] ='{FONTE}';
tam = atoi(tam_aloc);
tam_entrada = strlen(entrada);
id_area = entrada[tam_entrada+vazio];
}//FIM 'a'
if(operacao == 'c'){
i = 2; j = 0;
while(entrada[i]!= '{FONTE}'){
id_aloc[j] =entrada[i];
j++; i++;
}
id_aloc[j] = '{FONTE}';
id=atoi(id_aloc);
}//FIM 'c'
if(operacao == 'f'){
i = 2; j = 0;
while(entrada[i]!= '{FONTE}'){
id_aloc[j] = entrada[i];
j++; i++;
}
id = atoi(id_aloc);
}//FIM 'f'
if(operacao == 'x'){
i = 2; j = 0;
while(entrada[i]!= '{FONTE}'){
id_aloc[j] =entrada[i];
j++; i++;
}
id = atoi(id_aloc);
}//FIM 'x'
}
switch (operacao){
case 'a':{
if((consultaListaId(&listaint,id))||((verEspaco(&lista)) == MAX)||(tam > (MAX -(verEspaco(&lista)))) || (id < 0 || tam < 0))
printf("nao foi possivel alocar %d\n",id);
else{
switch (id_area){
case 'b':
aux = consultaBestFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
break;
case 'f':
aux = consultaFirstFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
break;
case 'w':
aux = consultaWorstFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
break;
default:
printf("nao foi possivel alocar %d\n",id);
break;
}
}
}
break;
case 'c': buscaBloco(&lista,id);
break;
case 'd': defragmentacao(&lista);
corrigirPosicao(&lista);
break;
case 'e':exit(0);
case 'f':
if(!consultaListaId(&listaint,id))
printf("\n");
else
retira_desalocacao(&lista,id);
break;
case 'l':areasLivre(&lista);
break;
case 'o':areasOcupadas(&lista);
break;
case 'x': experimento(&lista,&listaint,id);
break;
//
case 'q':funcao_teste(&lista);// USADO SOMENTE PARA TESTE DE CONSTRUCAO DO PROGRAMA
break;
default:
break;
}
}
return 0;
}
bool iniciarListas(ListaInt *i, Lista *l){ // INICIALIZAR LISTAS PARA FUNCAO "MAIN"
(*l) = NULL;
(*i) = NULL;
return true;
}
bool insere_Lista(Lista *l, int id, int tamanho){ //INSERE SOLICITACAO DE ALOCACAO
blocoLista *p;
Lista aux=NULL;
if((*l)->tamanho >= tamanho){
if(tamanho == (*l)->tamanho){
(*l)->id = id;
return true;
}
else{
p = (blocoLista*)malloc(sizeof(blocoLista));
if (!p){
printf("nao foi possivel alocar %d",id);
return false;
}
aux = (*l);
aux -> inicio = aux->inicio;
aux->id = id;
p->tamanho = aux->tamanho - tamanho;
aux->tamanho = tamanho;
p->prox = aux->prox;
aux->prox = p; p->ant = aux;
p->id = vazio; p->inicio = p->ant->tamanho + p->ant->inicio;
return true;
}
}
return true;
}
Lista areasLivre(Lista *l){
Lista p;
for(p=(*l); p!=NULL; p=p->prox){
if(p->id == vazio ){
printf("%d %d",p->inicio,p->tamanho);
printf("\n");
}
}
return NULL;
}
Lista areasOcupadas(Lista *l){
Lista p;
for(p=(*l); p!=NULL; p=p->prox){
if(p->id != vazio ){
printf("%d %d",p->inicio,p->tamanho);
printf("\n");
}
}
return NULL;
}
Lista buscaBloco(Lista *l, int id){//CONSULTA PARA IDENTIFICACAO DO BLOCO
Lista p=NULL;
for(p=(*l);p->prox!=NULL; p=p->prox){
if(id == p->id){
printf("%d\n",p->inicio);
return p;
}
}
if((p->prox == NULL)&&(id != p->id))
printf("requisicao nao atendida");
return p;
}
Lista consultaLista(Lista *l, int id){
Lista p;
for(p=(*l);(p)&&(p->id != id); p=p->prox);
return p;
}
Lista consultaBestFit(Lista *l, int tam){ //BUSCA BLOCO COM MENOR TAMANHO
Lista p, aux=NULL;
int soma = 0, menor = (MAX+1);
//se for vazio
for(p=(*l); p!=NULL; p = p->prox){
soma = soma + p->tamanho;
if(p->id == vazio){
if((p->tamanho < menor)&&(p->tamanho >= tam)){
menor = p->tamanho;
aux = p;
}
}
}
if(soma == MAX)
return aux;
return NULL;
}
Lista consultaFirstFit(Lista *l, int tam){//BUSCA BLOCO COM MENOR INDICE
Lista p = NULL, aux;
int soma = 0, menor = MAX+1;
// vazio
for(p=(*l); p!=NULL; p = p->prox){
soma = soma + p->tamanho;
if(p->id == vazio){
if(p->tamanho >= tam){
if(p->inicio < menor){
menor = p->inicio;
aux = p;
}
}
}
}
if(soma == MAX)
return aux;
return NULL;
}
Lista consultaWorstFit(Lista *l, int tam){ // BUSCA BLOCO COM MAIOR TAMANHO
Lista p, aux;
int soma = 0, maior = 0;
//se for vazio
for(p=(*l); p!=NULL; p = p->prox){
soma = soma + p->tamanho;
if(p->id == vazio){
if(p->tamanho > maior){
if(p->tamanho >= tam){
maior = p->tamanho;
aux = p;
}
}
}
}
if(soma == MAX)
return aux;
return NULL;
}
int verEspaco(Lista *l){//VERIFICA TAMANHO DE ESPACOS OCUPADOS/LIVRES
Lista p; int soma = 0;
for(p=(*l);p!=NULL; p=p->prox){
if(p->id !=vazio)
soma += p->tamanho;
}
return soma;
}
void inicializar(Lista *l){ //INICIALIZAR BLOCO DE ALOCACAO JÁ PREENCHIDO
blocoLista *p;
p = (blocoLista*)malloc(sizeof(blocoLista));
p->prox = *l; p->ant = NULL;
p->id = vazio; p->inicio = 0; p->tamanho = MAX;
(*l) = p;
}
bool retira_desalocacao(Lista *l, int id){ // FUNCAO PARA DESALOCACAO
Lista p, aux;
p = consultaLista(&(*l),id);
p->id = vazio;
if(p->prox->id == vazio){// verificação de blocos adjacentes depois do **prox
p->tamanho = p->prox->tamanho + p->tamanho;
aux = p->prox;
p->prox = aux->prox;
if(aux->prox != NULL)
aux->prox->ant = p;
free(aux);
return (*l);
}
if(p->ant){
if(p->ant->id == vazio){ // verificação de blocos adjacentes antes do **ant
p->tamanho = p->ant->tamanho + p->tamanho;
if(p->inicio > p->ant->inicio)
p-> inicio = p->ant->inicio;
aux = p->ant;
p->ant = aux->ant;
aux->ant->prox = p;
free(aux);
return (*l);
}
}
return (*l);
}
// FUNCOES PARA DEFRAGMENTACAO
Lista retirar_lista(Lista *l, int x){
Lista p, aux;
p = consultaLista(&(*l),x);
if(p->prox == NULL){
if(p->ant == NULL){
(*l) = p->prox;
free(p);
return (*l);
}
aux = p->ant;
aux->prox = p->prox;
free(p);
return (*l);
}
if(p->ant == NULL){
(*l) = p->prox;
p->prox->ant = NULL;
free(p);
return (*l);
}
else{
aux = p->ant;
aux->prox = p->prox;
p->prox->ant = aux;
free(p);
return (*l);
}
return (*l);
}
Lista defragmentacao(Lista *l){
blocoLista *p;
Lista aux, aux2 = *l;
int soma = 0;
p = (blocoLista*)malloc(sizeof(blocoLista));
for(aux=(*l);(aux); aux = aux->prox){//REALIZANDO A SOMA DO TAMANHO DE ESPACOS VAZIOS
if(aux->id == vazio){
soma += aux->tamanho;
}
}
for(aux=(*l);(aux); aux = aux->prox){// DELETANDO ESPAÇOS VAZIOS
if(aux->id == vazio){
retirar_lista(&(*l),aux->id);
}
}
while(aux2->prox!=NULL){
aux2=aux2->prox;
}
// CONSTRUINDO UM NOVO ESPACO VAZIO
p->tamanho = soma;
p->inicio = 0; // INDICE TEMPORARIO
p->prox = aux2->prox;
p->ant = aux2;
p->id = vazio;
aux2->prox = p;
return p;
}
void corrigirPosicao(Lista *l){
Lista aux;
for(aux=(*l); aux!=NULL; aux = aux->prox){// CORRIGINDO POSICOES
if(aux->ant == NULL){
aux->inicio = 0;
}
else{
aux->inicio = (aux->ant->inicio + aux->ant->tamanho);
}
}
}
void experimento(Lista *l, ListaInt *k, int num){
int i, j, tam_entrada, id, tam, cont = 0;
char operacao, id_aloc[30], tam_aloc[5], id_area, entrada[30];
Lista lista=(*l), aux, p; ListaInt listaint = (*k);
int a=0, b=0, c=0, d=0, soma=0;
float media = 0;
while( cont < num){
fflush(stdin);gets(entrada);
operacao = entrada[0];
if(operacao == 'a'){
id = 0; tam = 0;
i = 2; j = 0;
while(entrada[i] != ' '){
id_aloc[j] = entrada[i];
i++;
j++;
}
id_aloc[j]='{FONTE}';
id = atoi(id_aloc);
i = strlen(id_aloc) + 3;
j = 0;
while(entrada[i] != ' '){
tam_aloc[j] = entrada[i];
i++;
j++;
}
tam_aloc[j] ='{FONTE}';
tam = atoi(tam_aloc);
tam_entrada = strlen(entrada);
id_area = entrada[tam_entrada+vazio];
}
if(operacao == 'f'){
i = 2; j = 0;
while(entrada[i]!= '{FONTE}'){
id_aloc[j] = entrada[i];
j++; i++;
}
id = atoi(id_aloc);
}//FIM 'f'
switch (operacao){
case 'a':{
if((consultaListaId(&listaint,id))||((verEspaco(&lista)) == MAX)||(tam > (MAX -(verEspaco(&lista)))) || (id < 0 || tam < 0)){
b++;
}
else{
switch (id_area){
case 'b':
aux = consultaBestFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
a++;
break;
case 'f':
aux = consultaFirstFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
a++;
break;
case 'w':
aux = consultaWorstFit(&lista,tam);
insere_Lista(&aux,id,tam);
criaLista(&listaint,id);
a++;
break;
default:
b++;
break;
}
}
}
break;
case 'f':if(!consultaLista(&lista,id))
b++;
else
retira_desalocacao(&lista,id);
a++;
break;
default:
b++;
break;
} cont++;
}
for(p=(*l); p!=NULL; p=p->prox){// areas livres
if(p->id == vazio ){
soma = soma + p->tamanho;
c++;
}
if(p->id != vazio ){
d++;
}
}
media = soma/c;
printf("numero total de solicitacoes: %d\n",num);
printf("numero de solicitacoes atendidas: %d\n",a);
printf("numero de slots ocupados: %d\n",d);
printf("numero total de slots livres: %d\n",c);
printf("media do numero de slots nas areas livres: %.1f\n",media);
}
//
// LISTA AUXILIAR PARA GUARDAR OS IDENTIFICADORES
bool criaLista(ListaInt *i, int x){
identificador *p;
p = (identificador*)malloc(sizeof(identificador));
if(!p){
//printf("nao foi possivel alocar %d",x);
return false;
}
p->prox = *i;
*i = p;
p->chave = x;
return true;
}
bool consultaListaId(ListaInt *i, int x){
ListaInt p;
for(p=(*i); p!=NULL; p = p->prox){
if(p->chave == x){
return true;
}
}
return false;
}
//
Lista funcao_teste(Lista *l){//CONSULTA PARA IDENTIFICACAO DO BLOCO
Lista p;
for(p=(*l); p!=NULL; p = p->prox){
printf("%d\n",p->inicio);
}
return p;
}
Jogo da Velha com IA invencivel
Exemplo simples de socket em C/C++
Funções com número variável de argumentos
Nenhum comentário foi encontrado.
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Como bloquear pendrive em uma rede Linux
Um autoinstall.yaml para Ubuntu com foco em quem vai fazer máquina virtual
Instalar GRUB sem archinstall no Arch Linux em UEFI Problemático
Como impedir exclusão de arquivos por outros usuários no (Linux)
Alguém executou um rm e quase mata a Pixar! (6)
Formas seguras de instalar Debian Sid (9)
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (12)
Alguém pode me indicar um designer freelancer? [RESOLVIDO] (5)
Por que passar nas disciplinas da faculdade é ruim e ser reprovado é b... (6)









