Laborator 6. Alocarea dinamică a memoriei. Aplicații folosind tablouri
Obiectivele laboratorului
În acest laborator vom studia:
- alocarea dinamică: alocare, dealocare, memory leak (heap vs stack)
- stil de programare defensiv
- tablouri alocate dinamic - aplicații cu vectori și matrici
Materiale utile
Exerciții
-
Să se aloce dinamic un vector cu N elemente. N și elementele vectorului se vor citi de la STDIN.
-
Să se refacă exercițiul anterior, realizând și folosind funcții pentru fiecare operație elementară.
Exemplu
// funcția va citi numărul de elemente, va aloca un array cu acea dimensiune,
// apoi va citi elementele si le va salva in array (vector)
void read_vect(int *n, int **v);
void print_vect(int n, int *v);
De ce n
și v
au aceste tipuri de date?
HINT: Din main vom apela astfel:
int n;
int *v;
read_vect(&n, &v);
[...]
print_vect(n, v);
- Să se aloce dinamic o matrice n x m elemente. Toate datele sunt citite de la STDIN.
Exemplu
// funcția primește ca parametri dimensiunile unei matrice
// aloca tabloul și returnează pointerul
int **alloc_matrix(int n, int m);
// funcția primește dimensiunile unei matrice și matricea alocată
// va citi elementele și le va salva în matrice
void read_matrix(int n, int m, int **a);
// funcția va afișa elementele matricei
void print_matrix(int n, int m, int **a);
// funcție care primește toate datele necesare pentru
// eliberarea unei matrice alocată cu alloc_matrix
//
// trebuie să deduceți semnătura
... free_matrix(...);
Observație
Exercițiile de mai sus prezintă 2 modalități de organizare a codului în ceea ce privește citire și alocarea tablourilor.
1. Există o unică funcție care alocă & citește o matrice.
2. Există funcție specializată pentru alocare și alta pentru citire.
Pentru lucrul cu matrice preferăm să folosim a doua abordare (să avem o funcție pentru alocarea unei matrice și o funcție pentru citirea unei matrice). Discutați cu asistentul despre avantajele acestei abordări.
- Creați funcții care alocă/dealocă o matrice cu n linii, fiecare linie având un număr variabil de elemente. Toate dimensiunile se vor citi de la tastatură în funcția
main
.
a. Ce semnătură trebuie să aibă fiecare funcție? Implementați cele 2 funcții.
... alloc_matrix_varlen(...);
... free_matrix_varlen(...);
b. Pentru testare, creați un program care citește dimensiunile unei astfel de matrici, o populează linie cu linie (sus => jos, stânga => dreapta) cu numerele de la 1, 2, 3, 4, … cnt
(unde cnt
e numărul de elemente din matrice). Se va afișa matricea pe ecran.
Exemplu
4 // n = 4
1 4 2 3 // m[i] = lungimea liniei i (ex. i == 1, m[1] == 4 => 4 elemente)
// Outputul asociat este
1
2 3 4 5
6 7
8 9 10
- [BONUS] Scrieți un program în C prin care să demonstrați că o matrice statică are elementele alocate continuu, pe când la o matrice alocată dinamic liniile din memorie pot fi în zone neadiancente din RAM.
- P.S.1. La matrice alocată static
a[i][0]
este imediat dupaa[i-1][NMAX-1]
in memorie. - P.S.2. La matrice alocată dinamic, doar elementele de pe o linie sunt adiacente în memorie.