This shows you the differences between two versions of the page.
sde:teme:tema_ro_2 [2019/03/04 15:52] alexandru.radovici |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Tema 2 - Alocator de memorie ====== | ||
- | |||
- | Scopul acestei teme este realizarea unei biblioteci pentru alocarea de memorie numita ''sde_alloc''. Aceasta simuleaza modul | ||
- | in care este alocata memoria folosind alocatorul standard, adica functiile ''malloc'' si ''free''. | ||
- | |||
- | |||
- | ===== Informații generale ===== | ||
- | |||
- | <note important> | ||
- | Deadline: **17 Martie, ora 23:55**\\ | ||
- | Punctaj: **1 punct** din nota\\ | ||
- | Incarcarea temei: [[https://vmchecker.cs.pub.ro|vmchecker.cs.pub.ro]]\\ | ||
- | Incarcarea cu intarziere: **1 punct / zi** (maxim 4 zile)\\ | ||
- | </note> | ||
- | |||
- | |||
- | ===== Cunoștințe evaluate ===== | ||
- | |||
- | * Folosirea limbajului C | ||
- | * Folosirea structurilor de date | ||
- | * Intelegerea alocarii de memorie | ||
- | |||
- | ===== Reguli ===== | ||
- | |||
- | - Codul sursa trebuie sa fie indentat (-0.1p) | ||
- | - Tema trebuie sa contina un fisier Readme in care sa explicati cum ati facut tema (-0.1p) | ||
- | - Tema nu are voi sa aiba scurgeri (leak-uri) de memorie (-0.5p) | ||
- | |||
- | ===== Copierea ===== | ||
- | |||
- | Tema se rezolva individual. Orice tentativa de copiere va rezulta in **0p** pentru tema respectiva. Vom utiliza si sisteme automate de detectare a copierii. Daca avem dubii, va vom adresa intrebari suplimentare legate de tema. | ||
- | |||
- | ===== Intrebari ===== | ||
- | |||
- | Daca aveti intrebari legate de tema, va rugam sa scrieti un issue pe repository-ul de github [[https://github.com/upb-fils/sde.git|repository]] cu titlul de forma //[allocator] <titlul intrebarii voastre>//. Aveti nevoie de un cont de github pentru | ||
- | a scrie intrebari. | ||
- | |||
- | <note warning> | ||
- | **NU PUBLICATI COD SURSA**. Acesta va fi considerata copiere si se va penaliza cu 0p pe tema pentru voi. | ||
- | </note> | ||
- | |||
- | Daca doriti sa primiti un email cand se pun intrebari noi sau cand apar raspunsuri, accesati github [[https://github.com/upb-fils/sde|repository]] si faceti click pe //Watch//. | ||
- | |||
- | |||
- | |||
- | ===== Alocatorul de memorie ===== | ||
- | |||
- | Scopul acestei teme este scrierea unei biblioteci care gestioneaza alocarea de memorie. La initializare, biblioteca va aloca o zona de | ||
- | memorie mare (specificata de catre utilizator) folosind functiile standard de alocare (//malloc//). Zona de memorie alocata initial, numita in continuare //spatiu// va reprezenta spatiul in care biblioteca va face gestionarea. | ||
- | |||
- | Utilizatorul bibliotecii va folosi functiile acesteia pentru a aloca memorie in interiorul //spatiului//. | ||
- | |||
- | Pasii de folosire ai bibliotecii sunt: | ||
- | - initializarea unui //spatiu// folosind ''sde_memory_init'' | ||
- | - alocarea si dealocarea de memorie in //spatiu// folosind ''sde_alloc'' si ''sde_free'' | ||
- | - deinitializarea //spatiului// de memorie folosind ''sde_memory_free'' | ||
- | |||
- | Functiile bibliotecii sunt urmatoarele: | ||
- | |||
- | <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> | ||
- | |||
- | ==== Zone de memorie ==== | ||
- | Biblioteca aloca initial un //spatiu// de memorie. In interior, acest //spatiu// va contine mai multe //zone de memorie// alocate si | ||
- | nealocate (libere). Fiecare zona de memorie este caracterizata de doi parametri: | ||
- | * pozitia de inceput (offset) | ||
- | * lingimea ei (size) | ||
- | |||
- | Initial, tot //spatiul// de memorie este format din o singura zona care este nealocata care are pozitia 0 si lungimea | ||
- | egala cu lungimea //spatiului// de memorie. Dupa prima alocare, //spatiul// va contine doua zone: | ||
- | * una alocata (avand pozitia 0 si lungimea spacificata la alocare) | ||
- | * una nealocata avand pozitia imediat urmatoare zonei alocate si lungimea reprezentata de restul //spatiului// | ||
- | |||
- | Dupa mai multe alocari, //spatiul// de memorie va avea mai multe zone alocate si nealocate. | ||
- | |||
- | |||
- | {{ :sde:teme:memoryspace.png?nolink&650 | Memory Space }} | ||
- | |||
- | |||
- | ==== Erori ==== | ||
- | |||
- | Biblioteca poate intoarce una din urmatoarele erori | ||
- | |||
- | <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> | ||
- | |||
- | ==== Functii ==== | ||
- | |||
- | === sde_memory_init === | ||
- | Acesta functie realizeaza initializarea bibliotecii si a //spatiului//. | ||
- | |||
- | <code c> | ||
- | void * sde_memory_init (size_t size); | ||
- | </code> | ||
- | |||
- | == Parametrii == | ||
- | * **size**: dimensiunea //spatiului// de memorie care va fi alocat | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * Functia intoarce un pointer catre spatiu. | ||
- | * NULL in caz de eroare | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_MALLOC_FAIL - nu s-a putut aloca //spatiul// de memorie | ||
- | |||
- | Aceasta functie trebuie apelata inaintea oricarei alte functii din biblioteca. Implementarea functiei trebuie sa aloce //spatiul// de | ||
- | memorie (folosind functiile standard de alocare) si sa initializeze alte variabile necesare. | ||
- | |||
- | === sde_memory_free === | ||
- | Acesta functie face deinitializarea bibliotecii si a //spatiului//, practic dealoca toata memorie alocata. | ||
- | |||
- | <code c> | ||
- | void sde_memory_free (); | ||
- | </code> | ||
- | |||
- | == 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 | ||
- | |||
- | Aceasta functie trebuie apelata inaintea de oprirea programului. Dupa apelarea acestei functii, nu se mai poate folosi nici o | ||
- | alta functie din biblioteca (cu exceptia //sde_error//). Pentru folosirea ulterioara a bibliotecii, trebuie apelata din nou | ||
- | functia //sde_memory_init//. | ||
- | |||
- | === sde_alloc === | ||
- | Acesta functie face alocarea unei zone de memorie in interiorul //spatiului//. | ||
- | |||
- | <code c> | ||
- | void * sde_alloc (size_t size); | ||
- | </code> | ||
- | |||
- | == Parametrii == | ||
- | * **size**: dimensiunea memoriei care se doreste sa fie alocata in interiorul //spatiului//. | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * Functia intoarce un pointer catre zone de memorie alocata in interiorul //spatiului//. | ||
- | * NULL in caz de eroare | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | * SDE_NO_SPACE_LEFT - nu s-a putat aloca zona de memorie in interiorul //spatiului// deoarece nu mai exista destul spatiu disponibil. | ||
- | |||
- | <note> | ||
- | Adresa intoarsa este suma dintre: | ||
- | * adresa pointer-ului de inceput al //spatiului// | ||
- | * pozitia din interiorul spatiului | ||
- | |||
- | De exemplu, daca pointer-ul catre //spatiu// este ''space_address'' si pozitia in interiorul //spatiului// este ''n'', pointer-ul este calculat asa: | ||
- | <code c> | ||
- | int address; | ||
- | void *pointer; | ||
- | |||
- | address = (int)space_address; | ||
- | address = address + n; | ||
- | pointer = (void*)address; | ||
- | </code> | ||
- | </note> | ||
- | |||
- | === sde_zero_alloc === | ||
- | Acesta functie face alocarea unei zone de memorie in interiorul //spatiului// si o umple cu byte-ul 0. | ||
- | Practic este identica cu //sde_alloc//, doar ca adauga umplerea cu zero. | ||
- | |||
- | <code c> | ||
- | void * sde_zero_alloc (size_t size); | ||
- | </code> | ||
- | |||
- | == Parametrii == | ||
- | * **size**: dimensiunea memoriei care se doreste sa fie alocata in interiorul //spatiului//. | ||
- | |||
- | == Valoarea intoarsa == | ||
- | * Functia intoarce un pointer catre zona de memorie alocata in interiorul //spatiului//. | ||
- | * NULL in caz de eroare | ||
- | |||
- | == Erori == | ||
- | Erori posibile sunt: | ||
- | * SDE_OK - success | ||
- | * SDE_NO_INIT - functia este folosita inainte sa se fi initializat biblioteca | ||
- | * SDE_NO_SPACE_LEFT - nu s-a putut aloca zone de memorie in interiorul //spatiului// deoarece nu mai exista destul spatiu disponibil. | ||
- | |||
- | === 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//. | ||
- | |||
- | <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//. | ||
- | |||
- | <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 === | ||
- | Acesta functie afiseaza pe ecran toate zonele din interiorul //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 | ||
- | |||
- | * 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_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 //tema2//. | ||
- | |||
- | 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. | ||
- | |||
- | ===== Bonus ===== | ||
- | Pentru 2p suplimentare, implementati functiile: | ||
- | |||
- | <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> | ||
- | Bonusul se va puncta doar daca toate celelate teste pentru tema sunt cu success. | ||
- | </note> | ||
- | |||
- | |||
- | ===== 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> | ||
- | |||
- | |||
- | |||
- | |||
- | |||