This shows you the differences between two versions of the page.
sde:teme:tema_fr_2 [2019/03/15 13:12] alexandru.radovici |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Devoir 2 - Allocateur de mémoire ====== | ||
- | Le but de ce devoir est de créer une bibliothèque d’allocation de mémoire appelée ''sde_alloc''. Il simule la modalité | ||
- | dans laquel la mémoire est allouée à l’aide de l’allocateur standard, c’est-à-dire des fonctions ''malloc'' et ''free''. | ||
- | |||
- | ===== Informations générales ===== | ||
- | |||
- | <note important> | ||
- | Date limite: **18 Mars, 23:55**\\ | ||
- | Points: **1 point** de la note finale\\ | ||
- | Le devoir est à rendre sur: [[https://vmchecker.cs.pub.ro|vmchecker.cs.pub.ro]]\\ | ||
- | Rendre en retard: **1 points / jour** (maximum 4 jours)\\ | ||
- | </note> | ||
- | |||
- | |||
- | ===== Connaissance évaluée ===== | ||
- | |||
- | * Utiliser le langage C | ||
- | * Utiliser des structures de données | ||
- | * Comprendre l'allocation de mémoire | ||
- | |||
- | ===== Règles ===== | ||
- | |||
- | - Le code source doit être indenté (-0.1p) | ||
- | - Vous devez écrire un fichier nommé //Readme// et expliquer comment vous avez écrit les devoirs (-0.1p) | ||
- | - Le devoir ne doit pas à avoir des fuites de mémoire (-0.5p) | ||
- | |||
- | ===== Copiage ===== | ||
- | |||
- | Le devoir est individuel. Toute tentative de copie entraînera ** 0p ** pour les devoirs. Système anti-copie automatisé sera utilisé. | ||
- | |||
- | ===== Questions ===== | ||
- | |||
- | Si vous avez des questions concernant le devoir, posez-les en postant un //issue// sur le github [[https://github.com/upb-fils/sde|repository]] avec le format // [allocator] <le titre de votre question> //. Vous aurez besoin d'un compte github pour cela. | ||
- | |||
- | <note warning> | ||
- | **NE POSTEZ AUCUN CODE**. Ceci est considéré comme copiage et vous aller recevoir **0p** pour le devoir. | ||
- | </note> | ||
- | |||
- | Si vous souhaitez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github [[https://github.com/upb-fils/sde|repository]] et cliquez //Watch//. | ||
- | |||
- | |||
- | ===== Le Allocateur de mémoire ===== | ||
- | |||
- | Le but de ce devoir est d’écrire une bibliothèque qui gère l’allocation de mémoire. Lors de l'initialisation, la bibliothèque | ||
- | allouera une grande zone de mémoire (spécifiée par l'utilisateur) à l'aide des fonctions d'allocation | ||
- | standard (//malloc//). La zone mémoire initialement allouée, appelée //espace//, représente l'espace | ||
- | que la bibliothèque va gérer. | ||
- | |||
- | L'utilisateur de la bibliothèque utilisera ses fonctions pour allouer de la mémoire dans //l'espace//. | ||
- | |||
- | Les étapes d'utilisation de la bibliothèque sont les suivantes: | ||
- | - initialization d'un //espace// avec ''sde_memory_init'' | ||
- | - allouer et desallouer de la mémoire dans //l'espace// en utilisant ''sde_alloc'' et ''sde_free'' | ||
- | - désinitialisation de //l'espace// de mémoire en utilisant ''sde_memory_free'' | ||
- | |||
- | Les fonctions de la bibliothèque sont les suivantes: | ||
- | |||
- | <code c> | ||
- | // Initialize the system with size bytes of memory | ||
- | void * sde_memory_init (size_t size); | ||
- | |||
- | // Stop the system and free all resources | ||
- | void sde_memory_free (); | ||
- | |||
- | // Allocate memory (size in bytes) | ||
- | void * sde_alloc (size_t size); | ||
- | |||
- | // Reallocate memory | ||
- | void * sde_realloc (void * p, size_t size); | ||
- | |||
- | // Allocate memory and fill it with zero | ||
- | void * sde_zero_alloc (size_t size); | ||
- | |||
- | // Reallocate memory and fill the rest with zero | ||
- | void * sde_zero_realloc (void * p, size_t size); | ||
- | |||
- | // free memory | ||
- | void sde_free (void *p); | ||
- | |||
- | // Print all allocated (ALLOC: address -> size) | ||
- | void sde_print_allocated (); | ||
- | |||
- | // Print all free (FREE: address -> size) | ||
- | void sde_print_free (); | ||
- | |||
- | // Print all blocks (ALLOC: address -> size or FREE: address -> size) | ||
- | void sde_print (); | ||
- | |||
- | // Return the last error | ||
- | int sde_error (); | ||
- | </code> | ||
- | |||
- | ==== Zones de mémoire ==== | ||
- | La bibliothèque alloue initialement un //espace// de mémoire. A l'intérieur, cet //espace// contiendra | ||
- | plus de //zones de mémoire// allouées et non alloué (free). Chaque zone de | ||
- | mémoire est caractérisée par deux paramètres: | ||
- | * position (offset) | ||
- | * sa longueur (size) | ||
- | |||
- | Au debut, //l'espace// de mémoire est constitué d'une seule zone non allouée qui a une position 0 et une longueur | ||
- | égal à la longueur de //l'espace// de mémoire. Après la première allocation, //l'espace// contiendra deux zones: | ||
- | * une zone allouée (avec position 0 et la longueur spécifiée a l'allocation) | ||
- | * une zone non allouée suivant immédiatement la zone allouée et la longueur représentée par le reste de //l'espace// | ||
- | |||
- | Après plusieurs allocations, //l'espace// de mémoire aura plusieurs zones allouées et non allouées. | ||
- | |||
- | |||
- | {{ :sde:teme:memoryspace.png?nolink&650 | Memory Space }} | ||
- | |||
- | |||
- | ==== Erreurs ==== | ||
- | |||
- | La bibliothèque peut avoir l'une des erreurs suivantes | ||
- | |||
- | <code c> | ||
- | #define SDE_OK 0 // success | ||
- | #define SDE_NO_INIT -1 // you are trying to use a function before calling sde_memory_init | ||
- | #define SDE_ALREADY_INIT -2 // you are trying to use again sde_memory_init before sde_free | ||
- | #define SDE_MALLOC_FAIL -3 // the malloc function you used has returned null | ||
- | #define SDE_NO_SPACE_LEFT -4 // there is no space to allocated the requested size | ||
- | #define SDE_NOT_ALLOCATED -5 // the pointer was not allocated using the library | ||
- | #define SDE_OTHER -6 // any other error (for example from malloc or other memory function) | ||
- | </code> | ||
- | |||
- | ==== L'algorithme d'allocation ==== | ||
- | Pour l'allocation des zones, l'algorithme //first fit// sera utilisé. Cela signifie qu'à chaque affectation, vous devez rechercher les zones les plus proches du début de //l'espace// avec la taille inférieures ou égales avec la taille spécifiée par l'utilisateur. | ||
- | |||
- | ==== Fonctions ==== | ||
- | |||
- | === sde_memory_init === | ||
- | Cette fonction initialise la bibliothèque et //l'space//. | ||
- | |||
- | <code c> | ||
- | void * sde_memory_init (size_t size); | ||
- | </code> | ||
- | |||
- | == Paramètres == | ||
- | * **size**: la taille de //l'espace// de mémoire à allouer | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction renvoie un pointeur sur //l'espace//. | ||
- | * NULL en cas d'erreur | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_ALREADY_INIT - la bibliothèque a déjà été initialisée | ||
- | * SDE_MALLOC_FAIL - impossible d'allouer //espace// de mémoire | ||
- | |||
- | Cette fonction doit être appelée avant toute autre fonction de la bibliothèque. L'implémentation de la | ||
- | fonction doit allouer //l'espace// de mémoire (à l’aide des fonctions d’allocation standard) et initialiser | ||
- | les autres variables nécessaires. | ||
- | |||
- | === sde_memory_free === | ||
- | Cette fonction désinitialise la bibliothèque et //l'space//, pratiquement désallouée toute la mémoire allouée. | ||
- | |||
- | <code c> | ||
- | void sde_memory_free (); | ||
- | </code> | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction n'a pas de valeur de retour | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | |||
- | Cette fonction doit être appelée avant que le programme s’arrête. Après avoir appelé cette fonction, aucune ne | ||
- | peut utiliséeune une autre fonction dans la bibliothèque (sauf //sde_error//). Pour une utilisation | ||
- | ultérieure de la bibliothèque, il faut appeler la fonction //sde_memory_init//. | ||
- | |||
- | === sde_alloc === | ||
- | Cette fonction alluée une zone mémoire à l'intérieur de //l'space//. | ||
- | |||
- | <code c> | ||
- | void * sde_alloc (size_t size); | ||
- | </code> | ||
- | |||
- | == Paramètres == | ||
- | * **size**: la taille de la mémoire destinée à être allouée à l'intérieur de //l'espace//. | ||
- | |||
- | == Valeur de retour == | ||
- | * la fonction renvoie un pointeur sur la zone mémoire allouée à l'intérieur de //l'espace//. | ||
- | * NULL en cas d'erreur ou si le paramètre //size// est 0 | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | * SDE_NO_SPACE_LEFT - impossible d'allouer la zone mémoire à l'intrieur de //l'espace// car l'espace disponible est insuffisant. | ||
- | |||
- | <note> | ||
- | L'adresse de retour est la somme de: | ||
- | * l'adresse du pointeur de début de //l'espace// | ||
- | * la position à l'intérieur de //l'espace// | ||
- | |||
- | Par exemple, si le pointeur sur //l'espace// est ''space_address'' et que la position dans //l'espace// est ''n'', le pointeur est calculé comme suit: | ||
- | <code c> | ||
- | int address; | ||
- | void *pointer; | ||
- | |||
- | address = (int)space_address; | ||
- | address = address + n; | ||
- | pointer = (void*)address; | ||
- | </code> | ||
- | </note> | ||
- | |||
- | === sde_zero_alloc === | ||
- | Cette fonction alluée une zone mémoire à l'intérieur de //l'espace// et le remplit avec l'octet 0. | ||
- | Fondamentalement, il est identique à //sde_alloc//, elle ajoute simplement le remplissage zéro. | ||
- | |||
- | <code c> | ||
- | void * sde_zero_alloc (size_t size); | ||
- | </code> | ||
- | |||
- | == Paramètres == | ||
- | * **size**: la taille de la mémoire destinée à être allouée à l'intérieur de //l'espace//. | ||
- | |||
- | == Valeur de retour == | ||
- | * la fonction renvoie un pointeur sur la zone mémoire allouée à l'intérieur de //l'espace//. | ||
- | * NULL en cas d'erreur ou si le paramètre //size// est 0 | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | * SDE_NO_SPACE_LEFT - impossible d'allouer la zone mémoire à l'intrieur de //l'espace// car l'espace disponible est insuffisant. | ||
- | |||
- | === sde_free === | ||
- | Cette fonction supprime une zone mémoire allouée à l'intérieur de //l'espace//. | ||
- | |||
- | <code c> | ||
- | void sde_free (void *p); | ||
- | </code> | ||
- | |||
- | == Paramètres == | ||
- | * **p**: un pointeur précédemment renvoyé à l'une des fonctions d'allocation de bibliothèque. | ||
- | |||
- | |||
- | == Valeur de retour == | ||
- | * La fonction n'a pas de valeur de retour | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | * SDE_NOT_ALLOCATED - le pointeur pour lequel la désalocation a été demandée n'a pas été attribué à l'avance | ||
- | |||
- | |||
- | === sde_print_allocated === | ||
- | Cette fonction affiche à l'écran toutes les zones allouées dans //l'espace//. | ||
- | |||
- | <code c> | ||
- | void sde_print_allocated (); | ||
- | </code> | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction n'a pas de valeur de retour | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | |||
- | Le format d'affichage à l'écran est le suivant: | ||
- | <code> | ||
- | ALLOC: 0 100 | ||
- | ALLOC: 200 30 | ||
- | ALLOC: 120 30 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | L'ordre d'affichage des zones est pertinent. | ||
- | </note> | ||
- | |||
- | Cet exemple suggère qu'il y a 3 zones attribuées: | ||
- | * une en position 0 ayant une longueur de 100 octets | ||
- | * une en position 200 avec une longueur de 30 octets | ||
- | * une en position 120 ayant une longueur de 30 octets | ||
- | |||
- | === sde_print_free === | ||
- | Cette fonction affiche toutes les zones non allouées à l'intérieur de //l'space//. | ||
- | |||
- | <code c> | ||
- | void sde_print_free (); | ||
- | </code> | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction n'a pas de valeur de retour | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | |||
- | Le format d'affichage à l'écran est le suivant: | ||
- | <code> | ||
- | FREE: 150 50 | ||
- | FREE: 230 2400 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | L'ordre d'affichage des zones est pertinent. | ||
- | </note> | ||
- | |||
- | Cet exemple suggère qu'il existe 3 allocations non allouées: | ||
- | * une en position 150 ayant une longueur de 50 octets | ||
- | * une en position 230 ayant une longueur de 2400 octets | ||
- | |||
- | === sde_print === | ||
- | Cette fonction affiche à l'écran toutes les zones de //l'espace//, qu'elles soient allouées ou non. | ||
- | |||
- | <code c> | ||
- | void sde_print (); | ||
- | </code> | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction n'a pas de valeur de retour | ||
- | |||
- | == Erreurs == | ||
- | Les erreurs possibles sont: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - la fonction est utilisée avant l'initialisation de la bibliothèque | ||
- | |||
- | Le format d'affichage à l'écran est le suivant: | ||
- | <code> | ||
- | ALLOC: 0 100 | ||
- | ALLOC: 200 30 | ||
- | ALLOC: 120 30 | ||
- | FREE: 150 50 | ||
- | FREE: 230 2400 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | L'ordre d'affichage des zones est pertinent. | ||
- | </note> | ||
- | |||
- | Cet exemple suggère: | ||
- | |||
- | * qu'il y a 3 zones attribuées: | ||
- | * une en position 0 ayant une longueur de 100 octets | ||
- | * une en position 200 avec une longueur de 30 octets | ||
- | * une en position 120 ayant une longueur de 30 octets | ||
- | |||
- | * qu'il existe 3 allocations non allouées: | ||
- | * une en position 150 ayant une longueur de 50 octets | ||
- | * une en position 230 ayant une longueur de 2400 octets | ||
- | |||
- | === sde_error === | ||
- | Cette fonction renvoie le code d'erreur le plus récent. | ||
- | |||
- | <code c> | ||
- | int sde_error (); | ||
- | </code> | ||
- | |||
- | == Valeur de retour == | ||
- | * La fonction renvoie le code d'erreur le plus récent. | ||
- | |||
- | |||
- | Avant de revenir, chaque fonction de la bibliothèque définit un code d'erreur. Il peut être reçu par l'utilisateur | ||
- | en utilisant //sde_error//. | ||
- | |||
- | Par exemple, après un appel //sde_alloc//, printf affichera 0 si l’allocation a réussi ou | ||
- | un numéro d'erreur si //sde_alloc// avait une erreur. | ||
- | |||
- | <code c> | ||
- | sde_alloc (10); | ||
- | |||
- | printf ("%d\n", sde_error()); | ||
- | </code> | ||
- | |||
- | ===== Suggestions pour résoudre ===== | ||
- | Le devoir est relativement complexe par rapport au précédent. Un template pour le début du devoir est disponible dans [[https://github.com/upb-fils/sde|repository]] dans le répertoire //tema2//. | ||
- | Pour résoudre le devoir, nous suggérons les étapes suivantes: | ||
- | |||
- | - Ecrivez les fonctions ''sde_memory_init'', ''sde_memory_free'' et ''sde_error''. Celles-ci impliquent l'allocation de //l'espace// (avec malloc) et la déclaration d'une variable d'erreur. | ||
- | - Ecrivez les fonctions ''sde_alloc'', ''sde_free'' pour travailler pour une seule allocation | ||
- | - Écrire des structures de données pour conserver des zones de mémoire (plus de détails ci-dessous) | ||
- | - Ecrivez les fonctions ''sde_print_alloc'', ''sde_print_free'' et ''sde_print'' | ||
- | - Modifiez les fonctions ''sde_alloc'' et ''sde_free'' afin qu'elles fonctionnent avec un nombre fixe d'allocations maximum (afin que vous puissiez utiliser des structures de données de taille fixe pour conserver les allocations). | ||
- | - Modifier les fonctions ''sde_alloc'' et ''sde_free'' afin qu'elles fonctionnent avec un nombre illimité d'allocations (limitées uniquement par //l'espace// mémoire disponible) | ||
- | |||
- | === Structures de données === | ||
- | Pour conserver les zones dans la //l'espace// mémoire, vous pouvez utiliser les structures de données que vous préférez. Voici quelques suggestions: | ||
- | * deux chaînes de nombres, une pour la position (offset) et une pour la taille (size); les éléments doivent être triés par position. | ||
- | * une série de structures contenant deux éléments: la position et la longueur; la chaîne doit être triée par l'élément position | ||
- | * une liste de structures contenant deux éléments: position et longueur | ||
- | Au début, nous vous recommandons d'utiliser des structures de données de taille fixe, puis de passer à une taille variable. | ||
- | Pour les deux premières variantes des structures de données, le plus simple est l’allocation dynamique avec une | ||
- | taille initiale, et si la taille devient trop petite, la réallocation avec la longueur plus haut. | ||
- | |||
- | ===== Bonus ===== | ||
- | Pour 2p supplémentaire, implémentez les fonctions: | ||
- | |||
- | <code c> | ||
- | // Reallocate memory | ||
- | void * sde_realloc (void * p, size_t size); | ||
- | |||
- | // Reallocate memory and fill the rest with zero | ||
- | void * sde_zero_realloc (void * p, size_t size); | ||
- | </code> | ||
- | |||
- | <note> | ||
- | Le bonus ne sera noté que si tous les autres tests du devoir sont réussis. | ||
- | </note> | ||
- | |||
- | ===== Télécharger les devoirs ===== | ||
- | Les devoirs doivent être téléchargés sur [[https://vmchecker.cs.pub.ro|vmchecker]]. | ||
- | Connectez-vous avec votre nom d'utilisateur moodle, sélectionnez le cours //Systemes d'Explotation (FILS)// et téléchargez [[#archivage-de-devoir | l'archive de devoir]]. | ||
- | |||
- | ==== Readme ==== | ||
- | Le fichier //readme// a le format suivant: | ||
- | |||
- | <code> | ||
- | Nom complet | ||
- | Groupe | ||
- | |||
- | Une explication comment vous avez écrit le devoir, ce que vous avez utilisé, les idées principales. | ||
- | </code> | ||
- | |||
- | |||
- | ==== Archivage de devoir ==== | ||
- | Pour télécharger votre devoir, suivez les instructions suivantes: | ||
- | |||
- | - Créez une archive zip (pas rar, ace, 7zip ou autre) contenant: | ||
- | * vos fichiers antet (*.h) | ||
- | * vos fichiers source (*.c) | ||
- | * le fichier Makefile (déjà fait dans le template de devoir) | ||
- | * le fichier Readme | ||
- | - Connectez-vous avec [[https://vmchecker.cs.pub.ro|vmchecker]] | ||
- | - sélectionner le cours //Systemes d'Explotation (FILS)// | ||
- | - sélectionnez //2. Allocator// | ||
- | - télécharger l'archive | ||
- | |||
- | |||
- | <note> | ||
- | L'archive doit contenir les fichiers dans sa racine, pas dans un dossier. NE PAS archiver un dossier avec les fichiers, archiver DIRECTEMENT les fichiers. | ||
- | |||
- | NE PAS inclure les fichiers objets (*.o) et le fichier executable (Suggestion: utilisez //make clean// pour les supprimer avant d’archiver le devoir). | ||
- | </note> | ||
- | |||
- | Lorsque l'archive est téléchargée, //vmchecker// va exécuter: | ||
- | |||
- | <code bash> | ||
- | unzip archive.zip homework | ||
- | cd homework | ||
- | make build | ||
- | make run | ||
- | </code> |