This shows you the differences between two versions of the page.
sde:teme:tema_fr_2 [2019/03/04 01:36] 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: **17 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_MALLOC_FAIL -2 // the malloc function you used has returned null | ||
- | #define SDE_NO_SPACE_LEFT -3 // there is no space to allocated the requested size | ||
- | #define SDE_NOT_ALLOCATED -4 // the pointer was not allocated using the library | ||
- | </code> | ||
- | |||
- | ==== 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_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 | ||
- | |||
- | == 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 | ||
- | |||
- | == 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 === | ||
- | Acesta functie face dealocarea unei zone de memorie din interiorul //spatiului//. | ||
- | |||
- | <code c> | ||
- | void sde_free (void *p); | ||
- | </code> | ||
- | |||
- | == Parametrii == | ||
- | * **p**: un pointer ce a fost intors in prealabil de oricare din functiile de alocare ale bibliotecii. | ||
- | |||
- | |||
- | == Valoarea intoarsa == | ||
- | * Functia nu are valoare de intoarcere | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | * SDE_NOT_ALLOCATED - pointerul pentru care a fost ceruta dealocarea nu a fost alocat in prealabil | ||
- | |||
- | |||
- | === sde_print_allocated === | ||
- | Acesta functie afiseaza pe ecran toate zonele alocate din interiorul spatiului //spatiului//. | ||
- | |||
- | <code c> | ||
- | void sde_print_allocated (); | ||
- | </code> | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * functia nu intoarce valori | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | |||
- | Formatul afisarii pe ecran este urmatorul: | ||
- | <code> | ||
- | ALLOC: 0 100 | ||
- | ALLOC: 200 30 | ||
- | ALLOC: 120 30 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | Ordinea afisarii zonelor nu este relevanta. | ||
- | </note> | ||
- | |||
- | Acest exemplu sugereaza ca exista 3 zone alocate: | ||
- | * una la pozitia 0 avand lungimea de 100 de bytes | ||
- | * una la pozitia 200 avand lungimea de 30 de bytes | ||
- | * una la pozitia 120 avand lungimea de 30 de bytes | ||
- | |||
- | === sde_print_free === | ||
- | Acesta functie afiseaza pe ecran toate zonele nealocate din interiorul spatiului //spatiului//. | ||
- | |||
- | <code c> | ||
- | void sde_print_free (); | ||
- | </code> | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * functia nu intoarce valori | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | |||
- | Formatul afisarii pe ecran este urmatorul: | ||
- | <code> | ||
- | FREE: 150 50 | ||
- | FREE: 230 2400 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | Ordinea afisarii zonelor nu este relevanta. | ||
- | </note> | ||
- | |||
- | Acest exemplu sugereaza ca exista 3 nealocate alocate: | ||
- | * una la pozitia 150 avand lungimea de 50 de bytes | ||
- | * una la pozitia 230 avand lungimea de 2400 de bytes | ||
- | |||
- | |||
- | === sde_print_allocated === | ||
- | Acesta functie afiseaza pe ecran toate zonele din interiorul spatiului //spatiului//, atat alocate cat si nealocate. | ||
- | |||
- | <code c> | ||
- | void sde_print (); | ||
- | </code> | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * functia nu intoarce valori | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | |||
- | Formatul afisarii pe ecran este urmatorul: | ||
- | <code> | ||
- | ALLOC: 0 100 | ||
- | ALLOC: 200 30 | ||
- | ALLOC: 120 30 | ||
- | FREE: 150 50 | ||
- | FREE: 230 2400 | ||
- | </code> | ||
- | |||
- | <note> | ||
- | Ordinea afisarii zonelor nu este relevanta. | ||
- | </note> | ||
- | |||
- | Acest exemplu sugereaza ca exista 3 zone alocate: | ||
- | * una la pozitia 0 avand lungimea de 100 de bytes | ||
- | * una la pozitia 200 avand lungimea de 30 de bytes | ||
- | * una la pozitia 120 avand lungimea de 30 de bytes | ||
- | |||
- | |||
- | === sde_error === | ||
- | Acesta functie intoarce cel mai recent cod de eroare. | ||
- | |||
- | <code c> | ||
- | int sde_error (); | ||
- | </code> | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | * Functia intoarce cel mai recent cod de eroare | ||
- | |||
- | |||
- | Fiecare functie din biblioteca, inainte de a intoarce, seteaza un cod de eroare. Acesta poate fi primit de utilizator prin folosirea | ||
- | functiei //sde_error//. | ||
- | |||
- | Spre exemplu, in urma unui apel //sde_alloc//, printf va afisa 0 daca alocarea a fost facuta cu succes sau | ||
- | un numar de eroare in cazul in care //sde_alloc// a avut o eroare. | ||
- | |||
- | <code c> | ||
- | sde_alloc (10); | ||
- | |||
- | printf ("%d\n", sde_error()); | ||
- | </code> | ||
- | |||
- | ===== Sugestii de rezolvare ===== | ||
- | Tema este relativ complexa fata de cea anterioara. Un sablon pentru inceperea temei este disponibil in [[https://github.com/upb-fils/sde|repository]] in directorul //Devoir/allocator//. | ||
- | |||
- | Pentru a rezolva tema, va sugeram urmatorii pasi: | ||
- | |||
- | - Scrieti functiile ''sde_memory_init'', ''sde_memory_free'' si ''sde_error''. Acestea presupun alocarea //spatiului// (folosind malloc) si declararea unei variabile de eroare. | ||
- | - Scrieti functia ''sde_alloc'', ''sde_free'' astfel incat sa functioneze pentru o singura alocare | ||
- | - Scrieti structurile de date pentru retinerea zonelor de memorie (mai multe detalii mai jos) | ||
- | - Scrieti functiile ''sde_print_alloc'', ''sde_print_free'' si ''sde_print'' | ||
- | - Modificati functiile ''sde_alloc'' si ''sde_free'' astfel incat sa functioneze pentru un numar maxim fix de alocari (astfel incat sa puteti folosi structuri de date cu dimensiune fixa pentru a retine alocarile) | ||
- | - Modificati functiile ''sde_alloc'' si ''sde_free'' astfel incat sa functioneze pentru un numar nelimitat de alocari (limitat doar de //spatiul// de memorie disponibil) | ||
- | |||
- | === Structurile de date === | ||
- | Pentru retinerea zonelor din //spatiul// de memorie, puteti folosi ce structuri de date preferati. Aici sunt cateva sugestii: | ||
- | * doua siruri de numere, unul pentru pozitie (offset) si unul pentru dimensiune (size); elementele ar trebui sortate dupa pozitie. | ||
- | * un sir de structuri ce contin doua elemente: pozitia si lungimea; sirul ar trebui sortat dupa pozitie | ||
- | * o lista inlantuita de structuri care sa contina doua elemente: pozitie si lungime | ||
- | |||
- | Initial recomandam folosirea structurilor de date cu dimensiune fixa, apoi trecerea la dimensiune variabila. Pentru primele doua, | ||
- | cel mai simplu este alocarea dinamica cu o dimensiune initiala si, daca dimensiunea devine prea mica, realocarea lor cu lungime | ||
- | mai mare. | ||
- | |||
- | |||
- | ===== Trimiterea temei ===== | ||
- | Tema se va incarca pe [[https://vmchecker.cs.pub.ro|vmchecker]]. Logati-va pe site cu folosind utilizatorul de pe moodle, selectati cursul //Systemes d'Explotation (FILS)// si incarcati [[#arhiva-temei|arhiva temei]]. | ||
- | |||
- | ==== Readme ==== | ||
- | Fisierul readme are urmatorul format: | ||
- | |||
- | <code> | ||
- | Numele vostru intreg | ||
- | Grupa | ||
- | |||
- | Descrierea rezolvarii temei, de ce ati ales anumite solutii, etc. | ||
- | </code> | ||
- | |||
- | |||
- | ==== Arhiva temei ==== | ||
- | Pentru a incarca tema, urmariti pasii: | ||
- | |||
- | - Creati o arhiva zip (nu rar, ace, 7zip sau alt fomrat) care sa contina: | ||
- | * toate fisierele header (*.h) | ||
- | * toate fisierele sursa (*.c) | ||
- | * fisierul Makefile (este deja facut in sablonul temei) | ||
- | * fisierul Readme | ||
- | - logati-va pe [[https://vmchecker.cs.pub.ro|vmchecker]] | ||
- | - selectati cursul //Systemes d'Explotation(FILS)// | ||
- | - selectati //2. Alocator// | ||
- | - incarcati arhiva | ||
- | |||
- | |||
- | <note> | ||
- | Arhiva trebuie sa contina toate fisierele (principale) in radacina, nu in subdirectoare. NU arhivati directorul temei, arhivati DIRECT fisierele. | ||
- | |||
- | NU includeti fisierele obiect (*.o) si executabilul. (Sfat: folositi //make clean// pentru a sterge acestea inainte de arhivarea temei) | ||
- | </note> | ||
- | |||
- | Dupa ce incarcati arhiva, vmchecker va rula: | ||
- | |||
- | <code bash> | ||
- | unzip archive.zip homework | ||
- | cd homework | ||
- | make build | ||
- | make run | ||
- | </code> | ||
- | |||
- | |||
- | |||
- | |||
- | |||