char *p[20]; // Vector de 20 pointeri la caracterPentru atribuirea unei variabile întregi, var, celui de al treilea element al tabloului de pointeri*x[10], se va scrie:x[2] = &var;Pentru găsirea valorii lui var, se va scrie:y = *x[2]; //Valoarea lui var este atribuita lui yAtentie !. Trebuie facută distincţia între:int *v[10]; // Tablou de 10 pointeri la intregiint (*v)[10]; // Pointer la un tablou de 10 intregiPentru aceasta trebuie ţinut cont de faptul că * este un operator prefixat, iar [] şi () sunt operatoripostfixaţi. Deoarece prioritatea operatorilor postfixaţi este mai mare decât cea a operatorilor prefixaţi,atunci când se doreşte schimbarea priorităţii, trebuie folosite paranteze.6.2.5. Pointeri la pointeriUn tablou de pointeri este ceea ce numim pointeri la pointeri. Conceptul de tablou de pointeri estesimplu, deoarece indexarea tabloului conduce la clarificarea semnificaţiei lui.Un pointer la un pointer este o formă de indirectare multiplă sau un lanţ de pointeri.În cazul unui pointer la pointer, primul pointer conţine adresa celui de-al doilea pointer, care indică sprevariabila ce conţine valoarea dorită:Pointer Pointer VariabilăAdresă ---------> Adresă ---------> ValoareDeclararea indirectărilor multiple se face sub forma:Pentru a avea acces la o valoare indirectată printr-un pointer la pointer este necesară, de asemenea,utilizarea operatorului * de două ori, aşa cum se vede în exemplul următor:# include void main (void) {int x, *p, **q;x = 10;p = &x; /* p preia adresa lui x */q = &p; /* q preia adresa lui p */printf(" %d ", **q); } /*Se afiseaza valoarea lui x*/6.2.6. Alocarea dinamică a memorieiExistă două metode principale prin care un program C poate memora informaţii în memoriaprincipală a calculatorului.• Prima metodă foloseşte variabilele globale şi locale. În cazul variabilelor globale, memoria ce li sealocă este fixă pe tot timpul execuţiei programului. Pentru variabilele locale, programul alocă memorie înspaţiul stivei, în timpul execuţiei programului. Deşi variabilele locale sunt eficient de implementat, în C,de multe ori, utilizarea acestora, necesită cunoaşterea în avans a cantităţii de memorie necesare în fiecaresituaţie.• A doua metodă de alocare a memoriei, constă în utilizarea funcţiilor de alocare dinamică malloc()şi free(). Prin această metodă, un program alocă memorie pentru diversele informaţii în spaţiul memorieilibere numită heap, plasată între programul util şi memoria sa permanentă şi stivă. Se observă că stivacreşte în jos, iar dimensiunea acesteia depinde de program.H ighLowStivaM emorie liberápentru alocare(heap)V ar iabile globale(statice)Pr ogr am6M em oriaUn program cu multe funcţii recursive va folosi mult mai intens stiva în comparaţie cu un programce nu utilizeaza funcţii recursive, aceasta deoarece adresele de retur şi variabilele locale corespunzătoareacestor funcţii sunt salvate în stivă.
Funcţiile malloc() şi free()Aceste funcţii formează sistemul de alocare dinamică a memoriei în C şi fac parte din fisierulantet . Acestea lucrează împreună şi utilizează zona de memorie liberă plasată între codulprogram şi memoria sa permanentă (fixă) şi vârful stivei, în scopul stabilirii şi menţinerii unei liste avariabilelor memorate. De fiecare dată când se face o cerere de memorie, funcţia malloc() alocă o partedin memoria rămasă liberă. De fiecare dată când se face un apel de eliberare a memoriei, funcţia free()eliberează memorie sistemului.Declararea funcţiei malloc() se face sub forma:void *malloc (int numar_de_bytes);Aceasta întoarce un pointer de tip void, ceea ce înseamnă că trebuie utilizat un şablon explicit de tipatunci când pointerul returnat de malloc() se atribuie unui pointer de un alt tip. Dacă apelul lui malloc() seexecută cu succes, malloc() va returna un pointer la primul byte al zonei de memorie din heap ce a fostalocată. Dacă nu este suficientă memorie pentru a satisfce cererea malloc(), apare un eşec şi malloc()returnează NULL. Pentru determinarea exactă a numărului de bytes necesari fiecărui tip de date, se poatefolosi operatorul sizeof(). Prin aceasta, programele pot deveni portabile pe o varietate de sisteme.Funcţia free() returnează sistemului memoria alocată anterior cu malloc(). După eliberareamemoriei cu free(), aceasta se poate reutiliza folosind un apel malloc().Declararea funcţiei free() se realizează sub forma:free(void *p);Funcţia free() eliberează spaţiul indicat de p şi nu face nimic dacă p este NULL. Parametrul actual ptrebuie să fie un pointer la un spaţiu alocat anterior cu malloc(), calloc() sau realloc().Exemplu: Următorul program va aloca memorie pentru 40 de întregi, va afişa valoarea acestora, dupăcare eliberează zona, utilizând free():# include # include void main(void) {int t, *p;p = (int *) malloc(40*sizeof(int));if (!p) printf("Out of memory \n"); //Verificati daca p este un pointer corectelse {for (t=0; t