Skip to content

raresgoidescu/Dynamic-Memory-Allocator

Repository files navigation

GOIDESCU Rares-Stefan 2023-2024

Segregated Free Lists - Tema 1 SD Seria CA

Note despre tema

Ce mi s-a parut interesant?

Mi s-a parut interesanta ideea temei. Ideea mi-a starnit curiozitate si am inceput sa caut pe Internet tot felul de lucruri legate despre felul de a aloca memorie, nu simulata ca in tema, ci "pe bune" :).

Mi s-a parut interesant si faptul ca am fost lasati sa ne alegem unele lucruri in implementare. Acest lucru m-a facut sa ma gandesc "Care ar fi cea mai potrivita structura de date in aceasta situatie?".

De asemenea, bonusul a fost interesant, dar mai multe despre acesta mai jos.

Care a fost cea mai dificila parte a temei?

Din punctul meu de vedere, comanda MALLOC a fost cam cea mai dificila parte a temei. Acum ca am trecut de ea, nu mi se mai pare ceva out of this world si imi e greu sa explic exact de ce mi s-a parut cea mai grea, dar in timp ce o implementam interveneau tot felul de cazuri, exceptii, probleme de eficienta si FOARTE MULTE SIGSEGV-uri, dar acum ma simt mai pregatit sa lucrez cu memoria, deci pot spune ca a fost un exercitiu foarte folositor.

Ce cred ca as fi putut face mai bine?

In primul rand, modularizarea. Nu sunt foarte mandru de ea; nu e cea mai rea, dar nici cea mai buna. Simteam ca puteam face mai mult in aceasta privinta, insa nici cunostintele, nici timpul nu au fost de partea mea. O sa continui totusi sa caut feluri in care pot scrie mai bine diferite lucruri intrucat mai am cateva zile la dispozitie pana la deadline.

In al doilea rand, bonusul. Chiar daca sunt mandru de ideea care mi-a venit, sunt sigur ca exista moduri mult mai eficient de a face acest lucru, si din punct de vedere al memoriei si al timpului.


INIT_HEAP

Am implementat aceasta comanda destul de simplu. Am creat un resizeable array, la inceput cu dimensiunea egala cu numarul initial de liste dorite. Fiecare element al vectorului este de fapt o structura, in care tin minte lista de block-uri, dar sidiferite informatii despre aceasta.

MALLOC

Pentru block-urile marcate ca alocate am folosit o lista dublu inlantuita.

Implementarea pare destul de straight-forward, insa cazurile de exceptie erau cele care au ridicat multe obstacole. In principiu, caut un block suficient de mare. In caz ca il gasesc, verific daca trebuie sa il fragmentez sau nu. Daca trebuie fragmentat, il fragmentez, ramanand cu doua block-uri. Unul se duce in lista de block-uri alocate, iar celelalt isi cauta locul, sau isi face, in vectorul de liste, astfel incat sa pastram ideea de liste cu block-uri de aceeasi marime. Daca nu trebuie fragmentat, yay, doar il pun in lista de block-uri alocate. Daca nu exista un block suficient de mare, afisam un mesaj de eroare si nu se intampla nimic.

Despre fragmentare: Fara a lua in considerare bonusul, pare destul de simpla. Insa pentru a putea sti ce block-uri trebuie luate pentru reconstructie, am folosit o lista simplu inlantuita (pe post de stack) in care sa tin minte ID-ul (unic) fragmentarii curente.

READ

In primul rand, verific daca adresa de la care vrem sa citim este alocata, in caz contrar, SIGSEGV si DUMP_MEMORY.

In al doilea rand, verific daca putem citi cati octeti se vor a fi cititi. Daca am trece peste numarul de octeti (din block-urile continue), SIGSEGV si DUMP_MEMORY.

Nu in ultimul rand, daca nu se intampina nicio eroare, afisam octet cu octet continutul de la adresa de la care se doreste citi, avand in vedere sa trecem la block-ul urmator daca se termina actualul block.

WRITE

Verificarile sunt (aproape) identitce cu cele din cazul comenzii de READ.

Chiar si operatia de scriere este foarte asemanatoare. Parcurgem atat block-urile cat si string-ul primit de la tastatura octet cu octet si le egalam, pana cand terminam string-ul.

DUMP_MEMORY

Nu chiar cea mai usoara functie a temei intrucat ma pierdeam in calcule si a trebuit sa imi fac o structura in care sa retin diferite lucruri, precum numarul de apeluri, memorie, etc.

In principiu, printf si printf in loop-uri :).

FREE

In implementarea acestei comenzi, am cautat block-ul cu adresa respectiva in lista de block-uri alocate, iar in caz ca il gaseam, il marcam ca liber (il bagam inapoi in vectorul de liste). In caz contrar, afisam un mesaj de eroare corespunzator.

DESTROY_HEAP

Am implementat comanda, folosind o functie care elibereaza intreaga memorie ocupata de o lista dublu inlantuita, insa modificata pentru a-mi acomoda nevoile, astfel am ajuns la o functie destul de straight-forward.

BONUS

Bonusul parea simplu (cand am vazut primul exemplu), dar al doilea exemplu mi-a demonstrat ca nu e asa simplu. Ideea mea este de a pastra, pentru fiecare block, ID-urile (care sunt unice) fragmentarilor la care au luat parte block-urile, intr-o stiva (cred ca asa se implementeaza).

De fiecare data cand voiam sa dau FREE unui block, ma uitam prin cele libere si verificam daca exista vreun block care a rezultat din aceeasi ultima fragmentare ca block-ul dorit eliberat. Daca exista, reconstruim cate un block pana cand nu mai exista alt block rezultat din aceeasi fragmentare, moment in care punem block-ul rezultat in vectorul de liste. Daca nu exista, pur si simplu il trecem in vectorul de liste, asteptand sa fie eliberat (sau sa fi rezultat un block din reconstruire) care sa il considere potrivit pentru reconstruire. Si tot asa, pentru fiecare block.

PS

Sper ca am sters toate #ifdef DEBUG-urile...

Releases

No releases published

Packages

No packages published