Sunteți pe pagina 1din 20

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 mai
sigur, folosind operatorii new i delete.
Operatorul new permite alocarea de memorie n heap. El
se folosete ntr-una din formele:

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;

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;
}

Exemplul 2

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

Exemplul 3

Citii 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.

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);
}

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);

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++);
}

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;
}

Pointeri la funcii
Numele unei funcii reprezint adresa de memorie la care
ncepe funcia. Numele functiei este un pointer la funcie.
Ca i variabilele, pointerii la functii:
pot primi ca valori funcii;
pot fi transmii ca parametrii altor funcii
pot fi intori ca rezultate de ctre funcii
La declararea unui pointer ctre o funcie trebuiesc
precizate toate informaiile despre funcie, adic:
tipul funciei
numrul de parametri
tipul parametrilor
tip (*pf)(list_parametri_formali);

Pointeri la funcii
Apelul unei funcii prin intermediul unui pointer are forma:
(*pf)(list_parametri_actuali);
sau mai simplu, fr indirectare:
pf(list_parametri_actuali);
De exemplu, iniializarea unui tablou cu pointeri cu funciile
matematice uzuale se face prin:
double (*tabfun[])(double) = {sin, cos,
tan, exp, log};
Pentru a calcula rdcina de ordinul 5 din e este suficient
atribuirea:
y = (*tabfun[3])(0.2);
n acest mod putem transmite n lista de parametri a unei
funcii numele altei funcii

Exemplu: calculul unei integrale definite.


b

I f(x) dx
a

Definii o funcie pentru calculul unei integrale definite


prin metoda trapezelor,cu un numr fixat n de puncte
de diviziune:
f(a) f( b) n 1

f
(
x
)
dx

f
(
a

ih
)

a
2
i

cu h

ba
n

Folosii apoi aceast funcie pentru calculul unei integrale


definite cu o precizie dat . Aceast precizie este
atins n momentul n care diferena ntre dou
integrale, calculate cu n, respectiv 2n puncte de
diviziune este inferioar lui

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);
}

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); }

Declaratii complexe.
O declaratie complex este o combinaie de pointeri, tablouri
si functii. In acest scop se folosesc atributele:
() functie
[] tablou
* - pointer
care pot genera urmatoarele combinatii:
* () funcie ce returneaz un pointer
(*)() pointer la o funcie
* [] - tablou de pointeri
(*)[] pointer la tablou
[][] tablou bidimensional
Exist i combinaii incorecte, provenite din faptul c nu
este permis
declararea unui tablou de funcii
Declararea unei funcii ce returneaz un tablou

Declaratii complexe.
Combinatiile interzise sunt:
()[] funcie ce returneaz un tablou
[]() tablou de funcii
()() funcie ce returneaz o funcie
Regula dreapta stnga:
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 corespunztor
se continu substituia dreapta-stnga
se oprete procesul la ntlnirea tipului datei.

Declaratii complexe exemple.

int (* a[10]) ( );
tablou de 10
pointeri la
funcii ce returneaz int
double (*(*pf)())[3][4];
pointer la
o funcie ce returneaz un pointer
la un tablou cu 3 linii si 4 coloane de
double

Declaratii complexe.
Pentru creterea claritii, 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);

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

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;
}