1 / 20

Alocare dinamica a memoriei.

Alocare dinamica a memoriei. Asigura controlul direct, la executie al alocarii de memorie de catre programator prin apelul unor functii specifice, cu prototipurile in <stdlib.h> si <alloc.h> void* malloc(unsigned n); void* calloc(unsigned ne, unsigned dim);

von
Download Presentation

Alocare dinamica a memoriei.

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Alocare dinamica a memoriei. Asigura controlul direct, la executie al alocarii de memorie de catre programator prin apelul unor functii specifice, cu prototipurile in <stdlib.h>si <alloc.h> void* malloc(unsigned n); void* calloc(unsigned ne, unsigned dim); void* realloc(void* p, unsigned n); void free(void* p); În C++, alocarea dinamică se face mai simplu şi maisigur, folosind operatorii new şi delete. Operatorul new permite alocarea de memorie în heap. El se foloseşte într-una din formele:

  2. Alocare dinamica a memoriei. tip *p, *q, *r; //rezerva o zona de sizeof(tip) octeti p=new tip; //acelasi efect cu initializare cu valoarea // expresiei q=new tip(expresie); //rezerva o zona neinitializata de // expint*sizeof(tip) octeti r=new tip[expint]; Eliberarea memoriei alocate se face prin: delete p; //elibereaza memoria alocata pentru tablou delete [] r;

  3. Exemplul 1: #include <stdlib.h> #include <stdio.h> int main() { double *p; int n; scanf(“%d”, &n); p=(double*)malloc(n*sizeof(double)); if(p==NULL) { printf(“cerere neonorata\n”); exit(1); } return 0; }

  4. Exemplul 2 char* strdup(char* s) { char *p; p=(char*)malloc(strlen(s)+1); if(p) strcpy(p, s); return p; }

  5. Exemplul 3 Citiţi de la intrarea standard un şir de caractere de lungime necunoscută într-un vector alocat dinamic. Alocarea de memorie se va face progresiv, în incremente de lungime INC, după citirea a INC caractere se face o realocare.

  6. Exemplul 3: alocare incrementala a unui vector. char *citire() { char *p, *q; int n; unsigned dim=INC; p=q=(char*)malloc(dim); for(n=1; (*p=getchar())!=’\n’ &&*p!=EOF; n++) { if(n%INC==0) { dim+=INC; p=q=realloc(q,dim); p+=n; continue; } p++; } *p=’\0’; return realloc(q,n); }

  7. Pointeri la pointeri int x=10, *px=&x, **ppx=&px; void pschimb(int **pa, int **pb) { int *ptemp; ptemp=*pa; *pa=*pb; *pb=ptemp; } int *px, *py; pschimb(&px, &py);

  8. Tabele de pointeri. Cititi in memorie un fisier text (de exemplu fisierul standard de iesire). Liniile citite vor fi alocate dinamic prin pointeri dintr-un tablou de pointeri. #include <stdio.h> #include <stdlib.h> #define N 100 void afisare(char **tp, int n) { while(n--) printf(“%s\n”,*tp++); }

  9. Tabele de pointeri. int main() { //tabel de pointeri alocat static char *tp[N]; int lg=0; //numar de linii char linie[80]; while(gets(linie)) tp[lg++]=strdup(linie); afisare(tp, lg); return 0; }

  10. Pointeri la funcţii Numele unei funcţii reprezintă adresa de memorie la care începe funcţia. Numele functiei este un pointer la funcţie. Ca şi variabilele, pointerii la functii: • pot primi ca valori funcţii; • pot fi transmişi ca parametrii altor funcţii • pot fi intorşi ca rezultate de către funcţii La declararea unui pointer către o funcţie trebuiesc precizate toate informaţiile despre funcţie, adică: • tipul funcţiei • numărul de parametri • tipul parametrilor tip (*pf)(listă_parametri_formali);

  11. Pointeri la funcţii Apelul unei funcţii prin intermediul unui pointer are forma: • (*pf)(listă_parametri_actuali); sau mai simplu, fără indirectare: • pf(listă_parametri_actuali); De exemplu, iniţializarea unui tablou cu pointeri cu funcţiile matematice uzuale se face prin: • double (*tabfun[])(double) = {sin, cos, tan, exp, log}; Pentru a calcula rădăcina de ordinul 5 din e este suficientă atribuirea: • y = (*tabfun[3])(0.2); În acest mod putem transmite în lista de parametri a unei funcţii – numele altei funcţii

  12. Exemplu: calculul unei integrale definite. Definiţi o funcţie pentru calculul unei integrale definite prin metoda trapezelor,cu un număr fixat n de puncte de diviziune: Folosiţi apoi această funcţie pentru calculul unei integrale definite cu o precizie dată . Această precizie este atinsă în momentul în care diferenţa între două integrale, calculate cu n, respectiv 2n puncte de diviziune este inferioară lui 

  13. Calculul unei integrale definite. #include <math.h> double sinxp(); double trapez(double,double,int,double(*)(double)); double a=0.0, b=1.0, eps=1E-6; int N=10; void main(void) { int n=N; double In,I2n,vabs; In=trapez(a,b,n,sinxp); do { n*=2; I2n=trapez(a,b,n,sinxp); if((vabs=In-I2n)<0) vabs=-vabs; In=I2n; } while(vabs > eps); printf(“%6.2lf\n”, I2n); }

  14. Integrala unei functii definite. double trapez(double a,double b,int n,double(*f)(double)) { double h,s; int i; h=(b-a)/n; for(s=0.0,i=1;i<n;i++) s+=(*f)(a+i*h); s+=((*f)(a)+(*f)(b))/2.0; s*=h; return s; } double sinxp(double x) { return sin(x*x); }

  15. Declaratii complexe. O declaratie complexă este o combinaţie de pointeri, tablouri si functii. In acest scop se folosesc atributele: ()– functie [] – tablou * - pointer care pot genera urmatoarele combinatii: * () – funcţie ce returnează un pointer (*)() – pointer la o funcţie * [] - tablou de pointeri (*)[] – pointer la tablou [][] – tablou bidimensional Există şi combinaţii incorecte, provenite din faptul că nu este permisă • declararea unui tablou de funcţii • Declararea unei funcţii ce returnează un tablou

  16. Declaratii complexe. Combinatiile interzise sunt: • ()[] – funcţie ce returnează un tablou • []() – tablou de funcţii • ()() – funcţie ce returnează o funcţie Regula dreapta – stânga: • se incepe cu identificatorul • se caută în dreapta identificatorului un atribut • dacă nu există, se caută în partea stangă • se substituie atributul cu şablonul text corespunzător • se continuă substituţia dreapta-stânga • se opreşte procesul la întâlnirea tipului datei.

  17. Declaratii complexe exemple. int (* a[10]) ( ); • tablou de 10 • pointeri la • funcţii ce returnează int double (*(*pf)())[3][4]; • pointer la • o funcţie ce returnează un pointer • la un tablou cu 3 linii si 4 coloane de double

  18. Declaratii complexe. Pentru creşterea clarităţii, să definim progresiv noi tipuri folosind typedef /*tipul SIR=sir de caractere*/ typedef char *SIR; /*tipul VECTOR=tablou de 10float*/ typedef float VECTOR[10]; /*tipul MATRICE= tablou de 10x10 float*/ typedef float MATRICE[10][10]; /*tipul PFADRD=pointer la functie de argument double si rezultat double */ typedef double (*PFADRD)(double);

  19. Declaratii complexe. SIR s1, s2; VECTOR b, x; MATRICE a; PFADRD pf1;

  20. Tablouri multidimensionale typedef struct nod3{ int n; double *v; } N3; typedef struct nod2{ int n; N3 **pn3; } N2; N2 *alocmat() { N2 n2, *p2=&n2; int i, j, n; scanf("%d", &n); p2->n = n; p2->pn3=(N3**)malloc(n*sizeof(N3*)); for(i=0; i<n; i++) { p2->pn3[i]=(N3*)malloc(sizeof(N3)); scanf("%d", &p2->pn3[i]->n); p2->pn3[i]->v=(double*)malloc(p2->pn3[i]->n* sizeof(double)); } return p2; }

More Related