Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so:laboratoare:laborator-05 [2018/03/28 00:23]
costin.lupu [Exercițiul 9 - Lucrul cu stiva (0.5p)]
so:laboratoare:laborator-05 [2022/03/02 09:32] (current)
teodor_stefan.dutu [Exercițiul 0 - GSOC]
Line 1: Line 1:
 ====== Laborator 05 - Gestiunea memoriei ====== ====== Laborator 05 - Gestiunea memoriei ======
    
-===== Materiale ajutătoare ===== 
  
-  *[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-slides.pdf | lab05-slides.pdf]] 
-  *[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-refcard.pdf | lab05-refcard.pdf]] 
  
 ==== Nice to read ==== ==== Nice to read ====
  
   * TLPI - Chapter 7, ''​Memory Allocation''​   * TLPI - Chapter 7, ''​Memory Allocation''​
 +
 +===== Link-uri către secțiuni utile =====
 +
 +  * [[#​Gestiunea memoriei]]
 +  * [[#Spațiul de adresă al unui proces]]
 +  * [[#​Alocarea/​Dealocarea memoriei]]
 +  * [[#Lucru cu memoria - Probleme]]
 +    * [[#GDB - Detectarea zonei de acces nevalid de tip page fault]]
 +    * [[#mcheck - verificarea consistenței heap-ului]]
 +  * [[#Leak-uri de memorie]]
 +    * [[#​Valgrind]]
 +    * [[#mtrace]]
 +    * [[#Dublă dealocare]]
 +  ​
  ===== Gestiunea memoriei =====  ===== Gestiunea memoriei =====
  
Line 23: Line 34:
  
 Este, în consecință,​ fundamentală cunoașterea contextului în care acționează subsistemul de gestiune a memoriei și înțelegerea interfeței puse la dispoziție programatorului de către sistemul de operare. Este, în consecință,​ fundamentală cunoașterea contextului în care acționează subsistemul de gestiune a memoriei și înțelegerea interfeței puse la dispoziție programatorului de către sistemul de operare.
 +
 ===== Spațiul de adresă al unui proces ===== ===== Spațiul de adresă al unui proces =====
  
Line 65: Line 77:
 === .rodata === === .rodata ===
  
-Zona ''​.rodata''​ conține informație care poate fi doar citită, nu și modificată. Aici sunt stocate ​__constantele__:​ +Zona ''​.rodata''​ conține informație care poate fi doar citită, nu și modificată. Aici sunt stocate __literalii__:​
- +
-<code c> +
-const int a; +
-const char ptr[]; +
-</​code>​ +
- +
-<note important>​ +
-Precizarea este valabilă doar în cazul variabilelor constante **globale** (folosirea keyword-ului ''​const''​ la declararea variabilelor globale). Variabilele locale, chiar dacă sunt declarate ca fiind ''​const'',​ vor fi puse pe stivă, deci într-o zonă de memorie nemarcată ca //​read-only//​ și vor putea fi modificate prin intermediul unui pointer către acestea. +
-</​note>​ +
- +
-și __literalii__:​ +
 <code c> <code c>
 "​Hello,​ World!"​ "​Hello,​ World!"​
Line 83: Line 83:
 </​code>​ </​code>​
  
 +și __constantele__. Toate variabilele globale declarate cu keyword-ul ''​const''​ vor fi puse în ''​.rodata''​. Variabilele locale declarate ca fiind ''​const''​ vor fi puse pe stivă, deci într-o zonă de memorie nemarcată ca //​read-only//​ și vor putea fi modificate prin intermediul unui pointer către acestea. Un caz aparte îl reprezintă variabilele locale constante declarate cu keyword-ul ''​static''​ care vor fi puse în ''​.rodata'':​
 +<code c>
 +const int a;           /* în .rodata */
 +const char ptr[]; ​     /* în .rodata */
 +
 +void myfunc(void)
 +{
 +   int x;              /* pe stivă */
 +   const int y;        /* pe stivă */
 +   
 +   ​static const int z; /* în .rodata */
 +   
 +   ​static int p = 8;   /* în .data */
 +   ​static int q;       /* în .bss */
 +   ...
 +</​code>​
 ==== Stiva ==== ==== Stiva ====
  
Line 126: Line 142:
 Nu trebuie neapărat realizată dealocarea diverselor zone înainte de un apel [[http://​linux.die.net/​man/​3/​exit|exit]] sau înainte de încheierea programului pentru că acestea sunt automat eliberate de sistemul de operare. Nu trebuie neapărat realizată dealocarea diverselor zone înainte de un apel [[http://​linux.die.net/​man/​3/​exit|exit]] sau înainte de încheierea programului pentru că acestea sunt automat eliberate de sistemul de operare.
  
-**Atenție!** Pot apărea ​probleme ​și dacă se încearcă dealocarea aceleiași ​regiuni ​de memorie de două sau mai multe ori și se corup datele interne de management al zonelor alocate ​dintr-un heap.+<​note>​In majoritatea cazurilor, apar probleme dacă se încearcă dealocarea aceleiași ​zone de memoriede două ori. Aceasta e din cauza ca se corup datele interne de management al zonelor alocate. ​De obicei, kernelul semnalizeaza problema cu o intrerupere sincrona.</​note>​
 ==== Alocarea memoriei în Linux ==== ==== Alocarea memoriei în Linux ====
  
Line 245: Line 261:
 int *p = (int *)malloc(10 * sizeof(int));​ int *p = (int *)malloc(10 * sizeof(int));​
 </​code>​ </​code>​
-malloc întoarce //void *// care în C este automat convertit la tipul dorit. Mai mult, dacă se face cast, iar headerul ''​stdlib.h''​ necesar pentru funcția malloc nu este inclus, nu se va genera eroare! Pe anumite arhitecturi,​ acest caz poate conduce la un comportament nedefinit. Spre deosebire de C, în C++ este nevoie de cast. Mai multe detalii despre această problemă: ​ ​[[http://​www.cprogramming.com/​faq/​cgi-bin/​smartfaq.cgi?​answer=1047673478&​id=1043284351 | aici ]]+malloc întoarce //void *// care în C este automat convertit la tipul dorit. Mai mult, dacă se face cast, iar headerul ''​stdlib.h''​ necesar pentru funcția malloc nu este inclus, nu se va genera eroare! Pe anumite arhitecturi,​ acest caz poate conduce la un comportament nedefinit. Spre deosebire de C, în C++ este nevoie de cast. Discutia este elaborata ​ ​[[http://​www.cprogramming.com/​faq/​cgi-bin/​smartfaq.cgi?​answer=1047673478&​id=1043284351 | aici ]].
  
 Mai multe informații despre funcțiile de alocare găsiți în [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Unconstrained-Allocation.html#​Unconstrained-Allocationl| manualul bibliotecii standard C]] și în pagina de manual **man malloc**. Mai multe informații despre funcțiile de alocare găsiți în [[http://​www.gnu.org/​software/​libc/​manual/​html_node/​Unconstrained-Allocation.html#​Unconstrained-Allocationl| manualul bibliotecii standard C]] și în pagina de manual **man malloc**.
Line 313: Line 329:
  DIE (mat == NULL, "​HeapAlloc"​);​  DIE (mat == NULL, "​HeapAlloc"​);​
      
- for (i = 0; i < n; i++) {+ for (i = 0; i < m; i++) {
  mat[i] = HeapAlloc(processHeap,​ 0, n * sizeof(**mat));​  mat[i] = HeapAlloc(processHeap,​ 0, n * sizeof(**mat));​
  if (mat[i] == NULL) {  if (mat[i] == NULL) {
Line 838: Line 854:
 ====== Exerciții ====== ====== Exerciții ======
  
-===== Exercițiul 0 Joc interactiv (2p) =====+<note important>​ 
 +În cadrul laboratoarelor vom folosi repository-ul de git al materiei SO - https://​github.com/​systems-cs-pub-ro/​so. Va trebui sa clonați repository-ul pe masinile virtuale folosind comanda: ''​git clone https://​github.com/​systems-cs-pub-ro/​so''​. Dacă doriți să descărcați repositoryul în altă locație, folosiți comanda ''​git clone https://​github.com/​systems-cs-pub-ro/so ${target}''​.
  
-  * Detalii desfășurare [[http://​ocw.cs.pub.ro/courses/​so/​meta/​notare#​joc_interactiv|joc]].+Pentru a actualiza repository-ul,​ folosiți comanda ''​git pull origin master''​ din interiorul directorului în care se află repository-ulRecomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentăÎn cazul în care gitul detectează conflicte la nivelul vreunui fişier, folosiți următoarele comenzi pentru a vă păstra modificările:​ 
 +<​code>​ 
 +git stash 
 +git pull origin master 
 +git stash pop 
 +</code>
  
 +Pentru mai multe informații despre folosirea utilitarului git, urmați ghidul de la https://​gitimmersion.com.
 +</​note>​
  
 +<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile.
 +</​note>​
  
 +==== Exercițiul 0 - GSOC ====
  
-===== Linux (9p=====+Google Summer of Code este un program de vară în care studenții 
 +(indiferent de anul de studiusunt implicați în proiecte Open Source 
 +pentru a își dezvolta skill-urile de programare, fiind răsplătiți cu o 
 +bursă a cărei valoare [[https://​developers.google.com/​open-source/​gsoc/​help/​student-stipends|depinde de țară]] 
 +([[https://​developers.google.com/​open-source/​gsoc|pagină principală GSOC]]).
  
-<note important>​În rezolvarea laboratorului folosiți arhiva de sarcini [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-tasks.zip | lab05-tasks.zip]]</​note>​+UPB se află în top ca număr de studenți acceptați; în fiecare an fiind 
 +undeva la aprox30-40 de studenți acceptați. 
 +Vă încurajăm să aplicați!
  
-<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile. +===== Linux =====
-</​note>​ +
-==== Exercițiul 1 - Zone de stocare a variabilelor (0.5p) ​====+
  
-Intrați în directorul ''​1-counter''​ și implementați funcția ''​inc()''​ care întoarce ​de fiecare dată un întreg reprezentând numărul de apeluri până în momentul respectiv al funcției ''​inc''​ (**nu** aveți voie să folosiți variabile globale).+==== Exercițiul 1 - Zone de stocare a variabilelor ====
  
 +Intrați în directorul ''​1-counter''​ și implementați funcția ''​inc()''​ care întoarce de fiecare dată un întreg reprezentând numărul de apeluri până în momentul respectiv al funcției ''​inc''​ (**nu** aveți voie să folosiți variabile globale).
  
-==== Exercițiul 2 - Spațiul de adresă al unui proces ​(1p) ====+==== Exercițiul 2 - Spațiul de adresă al unui proces ====
   ​   ​
 Intrați în directorul ''​2-adr_space''​ și deschideți sursa ''​adr_space.c''​. În alt terminal compilați și rulați programul. Observați zonele de memorie din executabil în care sunt salvate variabilele,​ folosind comanda:<​code bash> Intrați în directorul ''​2-adr_space''​ și deschideți sursa ''​adr_space.c''​. În alt terminal compilați și rulați programul. Observați zonele de memorie din executabil în care sunt salvate variabilele,​ folosind comanda:<​code bash>
Line 874: Line 906:
 </​note>​ </​note>​
  
-==== Exercițiul 3 - Alocarea, realocarea și dezalocarea memoriei ​(1p) ====+==== Exercițiul 3 - Alocarea, realocarea și dezalocarea memoriei ====
  
 Intrați în directorul ''​3-alloc'',​ compilați și rulați programul ''​alloc''​. Intrați în directorul ''​3-alloc'',​ compilați și rulați programul ''​alloc''​.
Line 886: Line 918:
 Revedeți secțiunile [[#​valgrind|Valgrind]] și [[#alocarea memoriei in linux|Alocarea memoriei în Linux]] din laborator.</​note>​ Revedeți secțiunile [[#​valgrind|Valgrind]] și [[#alocarea memoriei in linux|Alocarea memoriei în Linux]] din laborator.</​note>​
  
-==== Exercițiul 4 - Rezolvarea unei probleme de tip Segmentation Fault (1p) ====+==== Exercițiul 4 - Rezolvarea unei probleme de tip Segmentation Fault ====
  
-Intrați în directorul ''​4-gdb''​ și inspectați sursa. Programul ar trebui să citescă un mesaj de la ''​stdin''​ și să-l afișeze. Compilați și rulați sursa. Rulați încă o dată programul din ''​gdb''​ (revedeți [[so:​laboratoare-2013:​resurse:​gdb#​rulare gdb|rularea unui program din gdb]]).+Intrați în directorul ''​4-gdb''​ și inspectați sursa. Programul ar trebui să citescă un mesaj de la ''​stdin''​, să îi transforme fiecare literă în majusculă ​și apoi să-l afișeze. Compilați și rulați sursa.
  
-Pentru a identifica exact unde crapă programul ​folosiți comanda ​[[http://​inside.mines.edu/​fs_home/​lwiencke/​elab/​gdb/​gdb_42.html ​backtrace]]. Pentru detalii despre comenzile ​din gdb folosițcomanda ''​help''​:<code bash> +Rulați încă o dată programul ​din ''​gdb''​ (revedeți [[so:​laboratoare-2013:​resurse:gdb#rulare gdb|rularea unui program ​din gdb]] ș ​[[#​acces nevalid | detectarea unui acces nevalid de tip page fault]]): 
-(gdb) help +<code bash> 
-</code>+(gdb) run 
 +Starting program: ​/home/​student/​lab05/​skel/​lin/​4-gdb/​fault  
 +Give input string:text
  
-Schimbațframe-ul curent cu frame-ul funcției ''​main''​ (revedeți [[#acces nevalid | detectarea unui acces nevalid de tip page fault]]):<code bash> +Program received signal SIGSEGV, Segmentation fault. 
-(gdb) frame main+0x0000555555554809 in upper_string (msg=0x0) at fault.c:​27 
 +27              while (msg[i] != '\0') { 
 +(gdb) bt 
 +#0  0x0000555555554809 in upper_string (msg=0x0) at fault.c:27 
 +#1  0x0000555555554835 in main (at fault.c:40 
 +(gdb) 
 </​code>​ </​code>​
  
-Inspectați valoarea variabilei ''​buf'':<​code bash> 
-(gdb) print buf 
-</​code>​ 
  
-Acum dorim să vedem de ce este ''​buf = NULL'',​ urmărind pașii:+Acum dorim să vedem de ce este ''​msg = NULL'',​ urmărind pașii:
    * Omorâți actualul proces:<​code bash>    * Omorâți actualul proces:<​code bash>
 (gdb) kill (gdb) kill
 </​code>​ </​code>​
-   * Puneți un breakpoint la începutul funcției ''​main'':<​code bash> +   * Puneți un breakpoint la începutul funcției ''​read_message'':<​code bash> 
-(gdb) break main+(gdb) break read_message
 </​code>​ </​code>​
-   ​* ​Rulați programul și inspectați valoarea lui ''​buf'' ​înainte și după apelul funcției ​''​malloc'' ​(folosiți ''​next''​ pentru a trece la instrucțiunea următoare, fără a urmări apelul ​de funcție).+   ​* ​Finalizați funcția:<​code bash> 
 +(gdb) finish 
 +Run till exit from #0  read_message () at fault.c:​14 
 +Give input string:​text 
 +0x0000555555554825 in main () at fault.c:​38 
 +38              message = read_message();​ 
 +Value returned is $1 = 0x0 
 +</​code>​ 
 + 
 +   * După cum puteți vedea, ​''​read_message'' ​returneză ''​0x0'' ​în loc de adresa mesajului citit.
    * Explicați sursa erorii, apoi rezolvați-o.    * Explicați sursa erorii, apoi rezolvați-o.
-==== Exercițiul 5 - Lucru cu memoria - Valgrind ​(1p) ====+ 
 +<note tip> 
 +  * https://​stackoverflow.com/​questions/​40290049/​why-does-gcc-return-0-instead-of-the-address-of-a-stack-allocated-variable 
 +  * https://​github.com/​gcc-mirror/​gcc/​commit/​f22a2cb7500755d69ee5965985d8621c735579c0 
 +</​note>​ 
 +==== Exercițiul 5 - Lucru cu memoria - Valgrind ====
  
 Intrați în directorul ''​5-struct''​ și completați fișierul ''​struct.c''​ conform comentariilor marcate cu ''​TODO''​. Intrați în directorul ''​5-struct''​ și completați fișierul ''​struct.c''​ conform comentariilor marcate cu ''​TODO''​.
Line 921: Line 971:
    * Revedeți secțiunea [[#​valgrind|Valgrind]] din laborator. ​    * Revedeți secțiunea [[#​valgrind|Valgrind]] din laborator. ​
  
-==== Exercițiul 6 - Stack overflow ​(2p) ====+==== Exercițiul 6 - Stack overflow ====
  
 Intrați în directorul 6-stack și inspectați sursa și completați problemele marcate cu //TODO1// astfel: Intrați în directorul 6-stack și inspectați sursa și completați problemele marcate cu //TODO1// astfel:
Line 927: Line 977:
       * în funcția ''​take_snapshot''​ salvați în structura de date ce reține imaginea stivei câmpurile adresă și valoare.       * în funcția ''​take_snapshot''​ salvați în structura de date ce reține imaginea stivei câmpurile adresă și valoare.
  
-Ce reține structura ''​stack_elements''?​+Ce reține structura ''​stack_element''?​
  
 Funcția ''​f2''​ pune pe stivă un vector de 3 întregi. În ce ordine sunt puse elementele vectorului pe stivă? Funcția ''​f2''​ pune pe stivă un vector de 3 întregi. În ce ordine sunt puse elementele vectorului pe stivă?
Line 934: Line 984:
  
 <note tip> <note tip>
-Dezasamblați executabilul. Observați că înainte de call ''​f2''​ se pune pe stivă ''​instruction pointer-ul(eip)''​ care este adresa primului byte de după call. La intrarea în funcție controlul s-a transmis de la caller la callee. Acesta din urmă salvează vechiul ''​base pointer(ebp)''​ iar ebp va conține adresa vârfului stivei.+Dezasamblați executabilul. Observați că înainte de call ''​f2''​ se pune pe stivă ''​instruction pointer-ul(eip) / rip (x86-64)''​ care este adresa primului byte de după call. La intrarea în funcție controlul s-a transmis de la caller la callee. Acesta din urmă salvează vechiul ''​base pointer(ebp) / rbp (x86-64)''​ iar ebp va conține adresa vârfului stivei.
 </​note>​ </​note>​
  
-Folosiți gdb pentru a afla informații despre cum este pus array-ul pe stivă ​și ce index trebuie suprascris: <code bash>+Folosiți gdb pentru a afla informații despre cum este pus array-ul pe stivă: <code bash>
 (gdb) break f2 (gdb) break f2
 (gdb) run (gdb) run
Line 943: Line 993:
 </​code>​ </​code>​
  
-Aveți grijă la proctectori ​de stivă [[https://​mudongliang.github.io/​2016/​05/​24/​stack-protector.html|Stack protectors]].+Aveți grijă la protectori ​de stivă [[https://​mudongliang.github.io/​2016/​05/​24/​stack-protector.html|Stack protectors]].
  
-In funcția ''​f2''​ bufferul ''​v''​ se află pe stivă sub adresa de return a funcției (IP-ul la care se întoarce programul dupa ce execută ''​f2''​). Scriind în bufferul ''​v''​ mai multe elemente decat are acesta alocate pe stivă, vom putea suprascrie adresa de return a lui ''​f2''​ cu o alta adresă (aici, adresa funcției ''​show_message''​). Atenție, după adresa de return este salvat pe stivă base pointerul și abia apoi găsim și bufferul ''​v''​.+In funcția ''​f2''​ bufferul ''​v''​ se află pe stivă sub adresa de return a funcției (IP-ul la care se întoarce programul dupa ce execută ''​f2''​). Scriind în bufferul ''​v''​ mai multe elemente decat are acesta alocate pe stivă, vom putea suprascrie adresa de return a lui ''​f2''​ cu o altă adresă (aici, adresa funcției ''​show_message''​). Atenție, după adresa de return este salvat pe stivă base pointerul și abia apoi găsim și bufferul ''​v''​.
  
 Folosindu-vă de vectorul ''​v''​ **fortați execuția** funcției ''​show_message''​ **fără** a o apela explicit. Astfel, după apelul funcției ''​f2'',​ fluxul programului nu se va mai întoarce în funcția ''​f1'',​ ci va executa ''​show_message''​. Urmăriți comentariile marcate cu //TODO2// (revedeți partea din laborator referitoare la [[#stiva | stivă ]]) Folosindu-vă de vectorul ''​v''​ **fortați execuția** funcției ''​show_message''​ **fără** a o apela explicit. Astfel, după apelul funcției ''​f2'',​ fluxul programului nu se va mai întoarce în funcția ''​f1'',​ ci va executa ''​show_message''​. Urmăriți comentariile marcate cu //TODO2// (revedeți partea din laborator referitoare la [[#stiva | stivă ]])
 +Folosiți-vă de cum arată stiva pentru a afla indexul în cadrul vectorului ''​vv''​ la care se află IP-ul.
 +
  
 <note tip> <note tip>
Line 953: Line 1005:
 </​note>​ </​note>​
  
-==== Exercițiul 7 - Detectare probleme de lucru cu memoria ​(1p) ====+==== Exercițiul 7 - Detectare probleme de lucru cu memoria ====
  
 În directorul ''​7-trim''​ analizați programul ''​trim.c'',​ compilați și rulați executabilul ''​trim''​. În directorul ''​7-trim''​ analizați programul ''​trim.c'',​ compilați și rulați executabilul ''​trim''​.
Line 959: Line 1011:
 Încercați să detectați problema folosind gdb (revedeți tehnicile folosite la exercițiul 3). Încercați să detectați problema folosind gdb (revedeți tehnicile folosite la exercițiul 3).
 Care este problema? Cum o rezolvați? Care este problema? Cum o rezolvați?
-==== Exercițiul 8 - Endianess ​(1p) ====+ 
 +==== Exercițiul 8 - Endianess ====
  
 Intrați în directorul ''​8-endian''​ și inspectați sursa ''​endian.c''​. Folosindu-vă de variabila ''​w''​ afișați ​ numărul ''​n=0xDEADBEEF''​. Intrați în directorul ''​8-endian''​ și inspectați sursa ''​endian.c''​. Folosindu-vă de variabila ''​w''​ afișați ​ numărul ''​n=0xDEADBEEF''​.
Line 966: Line 1019:
  
  
-==== Exercițiul 9 - Lucrul cu stiva (0.5p) ​====+<​hidden>​==== Exercițiul 9 - Lucrul cu stiva ====
  
 Intrați în directorul ''​9-bad_stack''​ și analizați fișierul ''​bad_stack.c''​. Compilați și rulați programul. Intrați în directorul ''​9-bad_stack''​ și analizați fișierul ''​bad_stack.c''​. Compilați și rulați programul.
  
-Se observă că în funcția ''​main'',​ prima oară se afișează valoarea din ''​str'',​ iar a doua oară nu. Observați că după ieșirea din funcția myfun() variabila ''​lab_so''​ nu mai este accesibilă deoarece se iese din stack frame-ul funcției myfun după return. Variabila va fi suprascrisă in cazul altor apeluri de funcții. Funcția myfun nu returneaza ​o adresă (așa cum se cere explicit) ci registrul eax conține valoarea 0x0 după return.+Se observă că în funcția ''​main'',​ prima oară se afișează valoarea din ''​str'',​ iar a doua oară nu. Observați că după ieșirea din funcția ​''​myfun()'' ​variabila ''​lab_so''​ nu mai este accesibilă deoarece se iese din stack frame-ul funcției ​''​myfun()'' ​după return. Variabila va fi suprascrisă in cazul altor apeluri de funcții. Funcția ​''​myfun()'' ​nu returnează ​o adresă (așa cum se cere explicit) ci registrul eax conține valoarea 0x0 după return.
  
 Care sunt tipurile de variabile care nu se află pe stivă? Care sunt tipurile de variabile care nu se află pe stivă?
  
-Modificați sursa, mai exact funcția ''​myfun()'',​ astfel încât variabila lab_so să fie accesibilă după return.+Modificați sursa, mai exact funcția ''​myfun()'',​ astfel încât variabila ​''​lab_so'' ​să fie accesibilă după return.
  
 <note tip>​Indicație:​ Mutați variabila ''​lab_so''​ din funcția ''​my_fun()''​ într-o altă zonă de memorie.</​note>​ <note tip>​Indicație:​ Mutați variabila ''​lab_so''​ din funcția ''​my_fun()''​ într-o altă zonă de memorie.</​note>​
-===== Exerciții BONUS (3 SO Karma) ​===== +</​hidden>​ 
 +===== Exerciții BONUS ===== 
  
 ==== BONUS Windows ==== ==== BONUS Windows ====
  
-=== 1 so karma - Realizarea unui wrapper pentru funcțiile malloc și free ===+=== Realizarea unui wrapper pentru funcțiile malloc și free ===
  
 Deschideți proiectul Visual Studio din directorul ''​malloc-wrapper''​ și inspectați cele două fișiere existente: ''​xmalloc.c''​ și ''​xmalloc.h''​. Deschideți proiectul Visual Studio din directorul ''​malloc-wrapper''​ și inspectați cele două fișiere existente: ''​xmalloc.c''​ și ''​xmalloc.h''​.
Line 991: Line 1045:
 De ce este mai dificil să se realizeze o funcție ''​xfree''​ care să realizeze aceleași operații? De ce este mai dificil să se realizeze o funcție ''​xfree''​ care să realizeze aceleași operații?
  
-=== 1 so karma - Program de test pentru wrapperul xmalloc ===+=== Program de test pentru wrapperul xmalloc ===
  
 Analizați fișierul ''​test.c''​ și implementați funcțiile ''​tensor_alloc'',​ respectiv ''​tensor_free''​ care alocă/​dealocă un vector tridimensional (tensor). Folosiți funcțiile ''​xmalloc''​ și ''​xfree''​ implementate în cadrul exercițiului anterior (urmăriți comentariile marcate cu ''​TODO''​). Analizați fișierul ''​test.c''​ și implementați funcțiile ''​tensor_alloc'',​ respectiv ''​tensor_free''​ care alocă/​dealocă un vector tridimensional (tensor). Folosiți funcțiile ''​xmalloc''​ și ''​xfree''​ implementate în cadrul exercițiului anterior (urmăriți comentariile marcate cu ''​TODO''​).
Line 997: Line 1051:
 ==== BONUS Linux ==== ==== BONUS Linux ====
  
-=== 1 so karma - Realizarea unei implementări sumare a funcției malloc ===+=== Realizarea unei implementări sumare a funcției malloc ===
  
 Urmăriți în ''​man''​ specificarea apelurilor [[http://​linux.die.net/​man/​2/​brk | brk]] și [[http://​linux.die.net/​man/​2/​sbrk | sbrk]]. Folosind acest apel de sistem, completați implementarea funcției [[http://​linux.die.net/​man/​3/​malloc | malloc ]] din sursa ''​my_malloc.c''​. Va trebui întâi să extindeți limita curentă a heap-ului (program break) cu valoarea cerută pentru alocare. Urmăriți în ''​man''​ specificarea apelurilor [[http://​linux.die.net/​man/​2/​brk | brk]] și [[http://​linux.die.net/​man/​2/​sbrk | sbrk]]. Folosind acest apel de sistem, completați implementarea funcției [[http://​linux.die.net/​man/​3/​malloc | malloc ]] din sursa ''​my_malloc.c''​. Va trebui întâi să extindeți limita curentă a heap-ului (program break) cu valoarea cerută pentru alocare.
Line 1007: Line 1061:
 <note tip>​Pentru rularea programului de test, nu uitați să exportați ''​LD_LIBRARY_PATH''​ (revedeți secțiunea de [[so:​laboratoare-2013:​laborator-01#​biblioteci in linux | biblioteci partajate din laboratorul 1]])</​note>​ <note tip>​Pentru rularea programului de test, nu uitați să exportați ''​LD_LIBRARY_PATH''​ (revedeți secțiunea de [[so:​laboratoare-2013:​laborator-01#​biblioteci in linux | biblioteci partajate din laboratorul 1]])</​note>​
  
-===== Soluții ===== 
- 
-[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-sol.zip | lab05-sol.zip]] 
  
 ===== Resurse utile ===== ===== Resurse utile =====
so/laboratoare/laborator-05.1522185808.txt.gz · Last modified: 2018/03/28 00:23 by costin.lupu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0