Sunteți pe pagina 1din 5

Alocarea dinamică de memorie pentru matrice

Tip_date* a=(tip_date*)malloc(n*sizeof(tip_date);
calloc(n,sizeof(tip_date);
Dacă pentru un vector dinamic putem aloca memorie folosin malloc sau calloc, pentru tablouri
multidimensionale (de dimensiune cal puțin 2) nu există funcție standard de alocare dinamică .
În schimb alocarea dinamică pentru vector de mai sus poate fi folosită pentru a aloca dinamic
memorie pentru un tablou multidimensional în mai mulți pași.
O matrice bidimensională poate fi considerată ca fiind un vector de vectori. (m = nr de vectori
sau nr. de linii, iar n = lungimea unui vector sau nr. de coloane).
Pentru o matrice vom considera un pointer că tre pointer că tre tip_date:
tip_date** a;
A;a cum am vă zut pointerul este un tip de date format dintr-un tip de date existent urmat de un
asterisc. Un astfel de pointer poate reține adresa de început a zonei de memorie alocată pentru
un vector. În descrierea de mai sus a este un pointer că tre tip_date*, adică a poate reține adresa
de început a unui vector avâ nd componente de tipul tip_date*, adică a este un vector de pointeri.
Fiecare pointer din acest vector va reține adresa de început a unei linii avâ nd elemente de tipul
tip_date.
*orice paranteză pă trată distruge un asterisc
a= (tip_date**)malloc(m*sizeof(tip_date*); //alocare memorie pentru vectorul de pointeri
for(int i=0;i<m;i++) // că tre liniile matricii
a[i]=(tip_date*)malloc(n*sizeof(tip_date)); // alocare memorie pentru linia i+1

//a[i][j]=*(a[i]+j) //mă duc la adresa lui a[i] și mă mut j că suțe mai încolo

Pentru a aloca memorie în stilul de mai sus avem nevoie de m+1 alocă ri dinamice de vectori.
Void matralloc (int m, int n, int tip_date** a) // a-ul e transmis prin valoare, nu se returneaza
adresa
{
a= (tip_date**)malloc(m*sizeof(tip_date*);
for(int i=0;i<m;i++)
a[i]=(tip_date*)malloc(n*sizeof(tip_date));
}
În exemplul de mai sus variabila a este transmisă prin valoare , deci este o copie a pointerului
transmis în funcție la apel.
În prima linie a-ul se inițializează cu adresa că tre vectorul de pointeri, valoare care evident ? nu
este returnată de funcția marcalloc.
Void main()
{
Int m,n;
Scanf(“%d%d”,&m,&n);
tip_date** a;
martalloc(m,n,a); //incorect
....
}
Variabila a din main nu se va inițializa cu adresa vectorului alocat în funcție.
I. Void matralloc (int m, int n, int tip_date*** a)
{
(*a)= (tip_date**)malloc(m*sizeof(tip_date*);
for(int i=0;i<m;i++)
(*a)[i]=(tip_date*)malloc(n*sizeof(tip_date));
}

Void main()
{
Int m,n;
Scanf(“%d%d”,&m,&n);
tip_date** a;
martalloc(m,n,&a); //corect!
....
}
Din cauză că alocarea dinamică se face în m+1 pași eliberatea evident se va face prin m+1
apeluri ale funcției free.

Void matrfree(int m, tip_date** a)


{
For(int i=0;i<m;i++)
Free(a[i]);
Free(a);
}
Pentru o matrice putem gâ ndi diverse metode de a aloca dinamic memorie pă strâ nd însă ideea
de variavilă că tre pointer că tre pointer că tre tip date pentru a reține matricea alocată dinamic.
Prezentă m în continuare o altă metodă consacrată . În această metodă vom face doar două
alocă ri dinamice: una pentru vectorul de pointeri că tre linii și a doua pentru a reține consecutiv
în memorie toate elementele matricei începâ nd cu elementele de pe prima linie, a doua linie... În
final trebuie ca pointerii din vectorul a să rețină adresele de început ale liniilor.
II. tip_date** a;
void matralloc1(int m, int n, tip_date*** a)
{
a=(tip_date**)malloc(m*sizeof(tip_date*));
(*a)[0]=(tip_date*)malloc(m*n*sizeof(tip_date));
for(int i=1;i<m;i++)
(*a[i])=(*a)[i-1]+n;
}
La metoda a 2-a la adoua alocare dianmică am alocat o zonă de memorie continuă de lingime
n*m că suțe de tipul elementelor matricei. Adresa acestei zone am reținut-o în pointerul a[0]
care practic reține adresa de început și a primei linii. Adresa de început a celei de a doua linii
a[1] este dată de adresa a[0] de la care ne deplasăm n că suțe la dreapta pentru a regă si
începutul celei de-a doua linii. În mod similar a[i], adresa celei de-a i+1 linii este adresa liniei
precedente (a[i-1]) de la care ne deplasăm spre dreapta n că suțe.
Eliberarea matricei alocate în stilul al 2-lea evident se va face prin două apeluri de funcție free.

void martfree(tip_pointer** a)
{
free(a[0]);
free(a);
}
*câ te alocă ri am atâ tea eliberă ri trebuie să am
Comparație între cele două metode
Prima metodă este „mai firească ”, mai ușor de înțeles, în consecință metoda 1 poate fii ușor
generalizată pentru matrice tridimensională , patrudimensională , etc. ( pentru o matrice k
dimensionlă alocă m un vector de pointeri că tre m matrici k-1 dimensionale unde m este prima
dimensiune a matricei k dimensionale, după care facem m alocă ri dinamice pentru matrici k-1
dimensionale).
Avantajele celei de-a 2-a metode:
1. Matoda a 2-a este mai rapidă atâ t la alocare câ t și la eliberare
2. Putem trimite/primi o matrice și citi/scrie din/în memorie într-un singur pas.
Trimiterea/ primirea fă câ ndu-se într-un/dintr-un flux de date (de exemplu dintr-un
fișier).

#define matalloc(m,n,a,t) a=(t**)malloc(m*sizeof(t*));\


for(int i=0;i<m;i++)\
a[i]=(t*)matalloc(n*sizeof(t));

#define matfree(m,a) for(int i=0;i<m;i++)\


free(a[i]);\
free(a);

int** a,m,n;
matalloc(m,n,a,int);
..........
matfree(m,a);
Temă:
1. Să se scrie macrocomenzi pentru alocarea dinamică și eliberarea memoriei pentru o
matrice în stilul al 2-lea.
2. Să se aloce dinamic memorie pentru o matrice triunghiulară de dimensiune n.
3. Să se scrie macrocomandă pentru alocarea dinamică a memoriei pentru o matrice
tridimensională de dimensiuni mxnxp. Să se scrie și macrocomandă pentru eliberare de
memorie pentru o astfel de matrice.
void matrsort(int m, int n, float** a) //fac modifică ri la adresă dar nu modific adresa
{
float* s=(float*)calloc(m,sizeof(float));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
s[i]+=a[i][j];
for(int i=0;i<m-1;i++)
for(int j=i+1;j<m;j++)
if(s[i]>s[j])
{
inter(s[i],s[j]);
inter(a[i],a[j]);
}
free(s);
}
inter este macrocomandă definită în cursurile anterioare. 😊
La pă rosirea fincției matrsort a[0] va reține adresa liniei care are suma cea mai mică. a[1] reține
adresa urmă toarei linii ca sumă , etc.
void main()
{
int m,n;
float** a;
scanf(“%d%d”,&m,&n);
matalloc(m,n,a,float)
//citire de matrice a
matrsort(m,n,a);
//afișare matrice a
matfree(m,a)
}

S-ar putea să vă placă și