rendered paste body#include "mem.h"#include <stdio.h>#include <stdlib.h>typedef struct fb{ size_t taille; struct fb *next;}fb_t;typedef struct ab{ size_t taille;}ab_t;static mem_fit_function_t *fonctionRecherche;static fb_t *tete;static char *memory;static size_t tailleMemoire;void mem_init(char *mem, size_t taille){ fb_t *nouveauBloc; memory = mem; tailleMemoire = taille; nouveauBloc = (fb_t*) memory; nouveauBloc->taille = tailleMemoire; nouveauBloc->next = NULL; tete = nouveauBloc; fonctionRecherche = mem_fit_first;}void mem_show(void (*print)(void *, size_t, int free)){ void* courantMem = (void*) memory; fb_t *courantFb = tete; ab_t *ab; size_t tailleBlocCourant; while((char*)courantMem < memory + tailleMemoire) { while((void*)courantFb != (void*)courantMem && (char*)courantMem < memory + tailleMemoire) { ab = (ab_t*)courantMem; tailleBlocCourant = ab->taille; print(courantMem, tailleBlocCourant, 0); courantMem = (char*)courantMem + tailleBlocCourant; } if(courantFb) { tailleBlocCourant = courantFb->taille; print(courantMem, tailleBlocCourant, 1); courantFb = courantFb->next; courantMem = (char*)courantMem + tailleBlocCourant; } } }/*Post-Cond :prevRet pointe sur un pointeur le bloc prcdant celui renvoy. * Si le bloc renvoy est le premier, prevRet pointe sur un pointeur qui vaut nul */fb_t *mem_fit_first(fb_t *fb, size_t taille, fb_t** prevRet){ fb_t *courant=fb, *prev=NULL; while(courant) { if(courant->taille >= taille) { *prevRet = prev; return courant; } prev = courant; courant = courant->next; } return NULL;}fb_t *mem_fit_best(fb_t *fb, size_t taille, fb_t** prevRet){ fb_t *prevBest, *fbBest, *prev, *courant; int residuMin, residuCourant; prev = NULL; courant = fb; prevBest = NULL; fbBest = NULL; residuMin = tailleMemoire; while(courant) { residuCourant = courant->taille - taille; if(residuCourant < residuMin) { residuMin = residuCourant; prevBest = prev; fbBest = courant; } prev = courant; courant = courant->next; } *prevRet = prevBest; return fbBest;}fb_t *mem_fit_worst(fb_t *fb, size_t taille, fb_t** prevRet){ fb_t *prevBest, *fbBest, *prev, *courant; int residuMax, residuCourant; prev = NULL; courant = fb; prevBest = NULL; fbBest = NULL; residuMax = 0; while(courant) { residuCourant = courant->taille - taille; if(residuCourant > residuMax) { residuMax = residuCourant; prevBest = prev; fbBest = courant; } prev = courant; courant = courant->next; } *prevRet = prevBest; return fbBest;}void *mem_alloc(size_t tailleAlloc){ fb_t *blocPrev, *blocSuiv; fb_t *blocUtilise;//descripteur du bloc libre avant allocation ab_t *blocAlloue;//descripteur du bloc allouer size_t tailleAlignee; size_t tailleLibre; //on verifie que la taille demand + le descripteur de bloc allou soit au moins //gale a la taille d'un descripteur de bloc libre de faon a pouvoir liberer ce bloc if(tailleAlloc + sizeof(ab_t) < sizeof(fb_t)) { tailleAlloc = sizeof(fb_t); } //recherche d'un bloc blocUtilise = fonctionRecherche(tete, tailleAlloc+sizeof(ab_t), &blocPrev); //aucun bloc disponible if(!blocUtilise) { return NULL; } blocSuiv = blocUtilise->next; tailleLibre = blocUtilise->taille; //alloc blocAlloue = (ab_t*) blocUtilise; tailleAlignee = tailleAlloc + (sizeof(size_t) - 1 - (tailleAlloc-1) % sizeof(tailleAlloc)); blocAlloue->taille = sizeof(ab_t) + tailleAlignee; //on positionne le nouveau fb if(tailleLibre > blocAlloue->taille) { int diff = tailleLibre - blocAlloue->taille; //Si on a pas assez de place aprs allocation pour un descripteur de bloc libre, //on augmente le bloc allou pour qu'il fasse la taille du bloc libre if( diff >= sizeof(fb_t)) { fb_t *nouveau; nouveau = (fb_t *)(((char*) blocUtilise) + blocAlloue->taille); nouveau->taille = diff; nouveau->next = blocSuiv; if(blocPrev == NULL) tete = nouveau; else blocPrev->next = nouveau; // printf("cas assez de place : blocUtilise : %p, blocPrev : %p sizeof(fb_t) %ld\n", blocUtilise, blocPrev, sizeof(fb_t)); } else { blocAlloue->taille = tailleLibre; // printf("cas bug : blocUtilise : %p, blocPrev : %p\n", blocUtilise, blocPrev); } } //les blocs libre et align sont de la mme taille, //on supprime le bloc libre if(tailleLibre == blocAlloue->taille) { if(blocPrev == NULL) tete = blocSuiv; else blocPrev->next = blocSuiv; }/* if((char*)blocAlloue + sizeof(ab_t) >= memory + tailleMemoire) { printf("BOOOOOM\n"); printf("bloc Utilus : %p, bloc Allou %p\n", blocUtilise, blocUtilise); exit(1); } if(blocAlloue->taille > tailleMemoire) { printf("BOOOOOM2\n"); printf("bloc Utilus : %p, bloc Allou %p\n", blocUtilise, blocUtilise); exit(1); }*/ return (void *) ( (char*)blocAlloue + sizeof(ab_t));}void mem_free(void* zone) { struct fb* nouveau; nouveau = (struct fb*) (((char *) zone) - sizeof(struct ab)); nouveau->taille = ((struct ab*) nouveau)->taille; if ((tete == NULL) || (((struct fb*) zone) < tete)) { nouveau->next = tete; //nouvelle tete tete = nouveau; if (nouveau->next != NULL) { //fusion if (nouveau->next == (struct fb*) (((char *) nouveau) + nouveau->taille)) { nouveau->taille = nouveau->taille + (nouveau->next)->taille; nouveau->next = (nouveau->next)->next; } } } else { struct fb *prev, *courant; courant = tete; prev = courant; while ((courant != NULL) && (courant < nouveau)) { prev = courant; courant = courant->next; } if (courant > nouveau) { prev->next = nouveau; nouveau->next = courant; if (nouveau->next != NULL) { //fusion if (nouveau->next == (struct fb*) (((char *) nouveau) + nouveau->taille)) { nouveau->taille = nouveau->taille + (nouveau->next)->taille; nouveau->next = (nouveau->next)->next; } } if (prev->next == (struct fb*) (((char *) prev) + prev->taille)) { prev->taille = prev->taille + (prev->next)->taille; prev->next = (prev->next)->next; } } }}