Gerenciamento de Área de Alocação Dinâmica (Listas Encadeadas)
Publicado por Danilo Azevedo (última atualização em 23/07/2014)
[ Hits: 3.175 ]
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;
}
Script MakePach para correção de platarforma 32 bits para 64
[C] Listas Duplamente Encadeadas
Árvore AVL, usando arquivos para armazenamento de dados
Nenhum comentário foi encontrado.
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
Como usar Gpaste no ambiente Cinnamon
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
VOL já não é mais como antes? (9)
É normal não gostar de KDE? (13)
E aí? O Warsaw já está funcionando no Debian 13? [RESOLVIDO] (15)
Secure boot, artigo interessante, nada técnico. (4)
copiar library para diretorio /usr/share/..... su com Falha na a... (1)









