You are on page 1of 13

ALOCAREA DINAMIC A MEMORIEI

1. Variabile de tip pointer Memoria unui calculator este organizat n octei, fiecare octet avnd asociat un numr numit adres. Variabilele ocup un numr de octei succesivi iar adresa primului octet este adresa variabilei. Un pointer este o variabil care conine adresa altei variabile. n C i C++ pointerii i vectorii sunt nrudii. n C i C++ declararea unei variabile pointer la (adres de) tipul de variabil tip se face astfel
tip *nume;

De exemplu:
int *adr; float *adresa;

struct elev { char nume[20], prenume[20]; float nota; int varsta; } elev *a; adr este o adres de variabile ntregi, adresa este adres de variabile reale, iar a este o adres de variabile de tip elev.

Adresa unei variabile se obine cu ajutorul operatorului de refereniere &:


&Nume_variabila;

adr1=&numar;

Variabilei adr1 i se atribuie adresa variabilei numar. Pentru a obine valoarea variabilei aflate la o adres memorat ntr-o variabil de tip pointer se folosete operatorul de derefereniere *.
int a=7, *adr=&a; cout<<*adr //se afiseaza valoarea memorata la adresa adr;

Variabila adr este un pointer la ntregi i este iniializat cu adresa lui a. Prin urmare se va afia valoarea 7.
elev a, *adr=&a; strcpy(a.nume, Ionescu); cout<<(*adr).nume

Operatorul unar * are prioritatea 2, prin urmare sunt necesare i parantezele pentru a ne referi la cmpul nume al variabilei memorate la adresa adr.

Se poate folosi i operatorul de selecie indirecta, ->, pentru a ne referi la un cmp al unei variabile structur a crei adres o cunoatem.
cout<<adr->nume;

ntre variabilele de tip pointer sunt permise atribuiri doar dac sunt pointeri la acelai tip de variabile.

2. Alocarea dinamic a memoriei Anumite variabile pot fi alocate dinamic i asta nseamn c: Spaiul necesar memorrii este rezervat ntr-un segment de memorie special destinat acestui scop, numit memorie HEAP. Pentru acest tip de variabile se rezerv spaiu de memorare n timpul executrii programului prin utilizarea unui anumit operator. 2

Atunci cnd variabila nu mai este util, spaiul de memorie pe care l-a ocupat poate fi eliberat prin utilizarea unui alt operator.

Mecanismul alocrii dinamice (C++): Se declar o variabil de tip pointer, de exemplu p, care permite memorarea unei adrese. Se aloc memorie pentru variabila dinamic prin operatorul new, iar rezultatul (o adres) este atribuit variabilei p. Variabila p va reine adresa variabilei alocat dinamic. Orice acces la variabila alocat dinamic se face prin intermediul variabilei p.

Operatori utilizai n C++: Operatorul new aloc spaiu n HEAP pentru o variabil dinamic. Dup alocare, adresa variabilei se atribuie lui p, unde p este o variabil de tip pointer ctre tip
p=new tip;

numrul de octei alocai n HEAP este egal cu numrul de octei ocupat de o variabil de tipul respectiv;

Operatorul delete elibereaz spaiul rezervat pentru variabila a crei adres este reinut n p. Dup eliberare coninutul variabilei p este nedefinit.
delete p;

int *adr1;//adr1 este o adresa de intregi adr1=new int; /* se rezerva spatiu de memorie pentru o variabila de tip int, variabila care va fi memorata la adresa adr1 */ *adr1=7;// la adr1 se memoreaza valoarea 7 cout<<*adr1;// se afiseaza continutul adresei adr1, adica 7 delete adr1;// se elibereaza memoria de la adresa adr1

Operaii cu variabile de tip pointer: Dac a este un pointer i n este un numr natural atunci putem calcula
a+n, a-n

unde a+n este adresa celui de-al n-lea obiect (variabil de tipul variabilei a crei adres este a) dup cel a crui adres este p. Tablouri: 3

In C i C++ numele unui vector este un pointer constant (nu poate fi modificat) ctre tipul de baz al vectorului. Este adresa primului element al vectorului, elementul cu indicele 0.
float a[10], *b;//atat a cat si b sunt adrese de numere reale a[7]=3; b=a;//la adresa lui b se memoreaza adresa primului element din a cout<<b[7]; /* se afiseaza continutul adresei aflate la 7 spatii (care depind de tipul variabilelor, in cazul nostru spatii pentru numere reale) distanta de adresa b. Adica este afisat 3 */ cout<<*(a+7)<<endl;// un alt mod de a afisa 3

n C i C++ avem urmtoarele echivalene

a[n]*(a+n)*(n+a)n[a]

fiecare termen nsemnnd valoarea variabilei memorate la n adrese distan de adresa a.

3. Liste: O list este identificat prin primul su element, numit cteodat i capul listei. Acest lucru se ntmpl deoarece, pornind de la primul nod, se pot identifica toate elementele listei. Pentru a marca sfritul unei liste care nu este circular, ultimul element al listei se va lega la pointerul nul, 0 in C++ i NULL n C. Mai jos este un exemplu de construire a unei stive, o list n care elementele sunt poziionate n ordinea invers citirii valorilor lor. Adic, primul element din list va fi ultimul element citit i ultimul element din list va fi primul element citit. Lista va avea elemente de tipul Nod, o structur cu dou cmpuri, un cmp pentru informaie i un cmp pentru legtura la urmtorul element din list.
#include<iostream.h> struct Nod { int info; Nod* adr_urm; };

Nod *v; int nr; void Adaug(Nod*& v, int nr) { Nod* c=new Nod; c->info=nr; c->adr_urm=v; v=c; } void Tip(Nod* v) { Nod* c=v;; while(c) { cout<<c->info<<endl; c=c->adr_urm; } } main() { cout<<"dati elementele listei, 0 pentru sfrasitul listei"<<endl; cout<<"numar=";cin>>nr; while (nr) { Adaug(v,nr); cout<<"numar=";cin>>nr; } Tip(v); }

n urmtorul exemplu este construit o coad, o list n care elementele sunt poziionate n ordinea citirii valorilor lor. De asemenea, exist dou funcii de inserare a unui nod, una dup un nod cu o anumit valoare, cealalt naintea unui nod cu o anumit valoare, i o funcie de tergere a unui nod cu o anumit valoare.
#include<iostream.h> struct Nod { int info; Nod* adr_urm; }; Nod *v, *sf;

int i; void Adaugare(Nod*& v, Nod*& sf, int val) { Nod* c; if (v==0) { v=new Nod; v->info=val; v->adr_urm=0; sf=v; } else { c=new Nod; sf->adr_urm=c; c->info=val; c->adr_urm=0; sf=c; } } void Inserare_dupa(Nod* v, Nod*& sf, int val, int val1) { Nod* c=v, *d; while (c->info!=val) c=c->adr_urm; d=new Nod; d->info=val1; d->adr_urm=c->adr_urm; c->adr_urm=d; if (d->adr_urm==0) sf=d; } void Inserare_inainte(Nod*& v, int val, int val1) { Nod*c, *d; if (v->info==val) { d=new Nod; d->info=val1;d->adr_urm=v;v=d; } else { c=v; while (c->adr_urm->info!=val) c=c->adr_urm; d=new Nod; d->info=val1;d->adr_urm=c->adr_urm;c->adr_urm=d; } } void Sterg(Nod*& v, Nod*& sf, int val) { Nod* c, *man; if(v->info==val)

{ man=v; v=v->adr_urm; } else { c=v; while (c->adr_urm->info!=val) c=c->adr_urm; man=c->adr_urm;c->adr_urm=man->adr_urm; if (man==sf) sf=c; } delete man; } void Tip(Nod* v) { Nod* c=v;; while(c) { cout<<c->info<<endl; c=c->adr_urm; } } main() { int nr,v_nod; cout<<"Dati elementele listei, 0 pentru sfarsitul listei"<<endl; cout<<"numar=";cin>>nr; v=sf=0; while (nr) { Adaugare(v,sf,nr); cout<<"numar=";cin>>nr; } Tip(v); cout<<"Dati valoarea unui nod si un numar care trebuie inserat dupa acel nod"<<endl; cout<<"valoare=";cin>>v_nod; cout<<"numar=";cin>>nr; Inserare_dupa(v,sf,v_nod,nr); Tip(v); cout<<"Dati valoarea unui nod si un numar care trebuie inserat inainte de acel nod"<<endl; cout<<"valoare=";cin>>v_nod; cout<<"numar=";cin>>nr; Inserare_inainte(v,v_nod,nr); Tip(v); cout<<"Dati valoarea unui nod care trebuie sters"<<endl; cout<<"valoare=";cin>>nr; Sterg(v,sf,nr); Tip(v); }

4. Alocare dinamic n C Funcia malloc aloc o zon de memorie i ntoarce un pointer la acea zon. Argumentul funciei malloc este reprezentat de mrimea zonei de memorie necesare pentru memorarea tipului de date spre care "pointeaz" rezultatul funciei malloc. Aceast mrime este obinut folosind funcia sizeof. De exemplu:
p=malloc(sizeof(int))

aloc spaiu de memorie pentru un numr ntreg a crui adres este memorat n p.

Funcia free elibereaz spaiul de memorie alocat pentru date spre care "pointeaz" argumentul funciei. De exemplu free(p) elibereaz spaiu de memorie rezervat pentru tipul de date a cror adresa este memorat n p.

Prototipurile funciilor malloc i free se afl n fiierul alloc.h.

Definirea n C a tipului nod, o structur cu dou cmpuri, un cmp de informaie i unul de legtur:
typedef struct { int inf; struct nod *leg; } nod;

Adugarea unui element ntr-o stiv se poate scrie cu ajutorul funciei:


nod *a_stiva(nod *v,int n) { nod *q; q=malloc(sizeof(nod)); q->inf=n; q->leg=v; v=q; return v; }

Adugarea unui element ntr-o coad se poate scrie cu ajutorul funciei:


nod *a_coada(nod *v, int n) { nod *r,*s; s=malloc(sizeof(nod)); s->inf=n; s->leg=NULL; if (!v) v=s; else { r=v; while(r->leg) r=r->leg; r->leg=s; } return v; }

Observm c att la adugarea ntr-o stiv, ct i la adugarea ntr-o coad rezultatul funciilor a_stiva i a_coada este un pointer la o variabil de tip nod. Acest pointer reprezint de fapt adresa primului element din list (adic a capului listei).

In funcia main, nainte de apelarea celor doua funcii, pointerul v trebuie iniializat cu pointerul NULL. Afiarea informaiilor memorate ntr-o list se poate realiza cu ajutorul funciei:
void listare(nod *v) { while(v) { printf("%d ",v->inf); v=v->leg; } printf("\n"); }

n urmtorul exemplu se creeaz o list circular cu n elemente. Din list se vor elimina pe rnd toate elementele, ncepnd cu elementul m.

#include <stdio.h>

#include <malloc.h> typedef struct { int inf; struct nod *leg; } nod; int main() { nod *p,*q,*r; int m,n,l,i,j; printf("dati numarul de obiecte\n"); scanf("%d", &n); printf("dati numarul obiectului cu care incepe eliminare\n"); scanf("%d", &m); printf("din cate in cate obiecte se elimina\n"); scanf("%d", &l); p=malloc(sizeof(nod)); p->inf=1; r=p; for (i=2;i<=n;i++) { q=malloc(sizeof(nod)); q->inf=i; r->leg=q; r=q; } q->leg=p; for (i=1;i<=m-1;i++) { q=p; p=p->leg; } printf("ordinea de eliminare este:\n"); for(i=1;i<=n-1;i++) { printf("%d ",p->inf); q->leg=p->leg; free(p); p=q; for (j=1;j<=l;j++) { q=p; p=p->leg; } } printf("%d\n",p->inf); free(p); return 0; }

10

n urmtorul exemplu este creat o list dublu nlnuit.


#include <stdio.h> #include <alloc.h> typedef struct { int inf; struct nod *leg_s,*leg_d; } nod; nod *nod0(int x) { nod *p; p=malloc(sizeof(nod)); p->inf=x; p->leg_s=NULL; p->leg_d=NULL; return p; } nod *adauga_s(nod *p,int x) { nod *q; q=malloc(sizeof(nod)); q->inf=x; q->leg_s=NULL; q->leg_d=p; p->leg_s=q; p=q; return p; } nod *adauga_d(nod *p,int x) { nod *q,*r; r=p; while (r->leg_d!=NULL) r=r->leg_d; q=malloc(sizeof(nod)); q->inf=x; q->leg_d=NULL; q->leg_s=r; r->leg_d=q; return p; } void listare(nod *p) { nod *r; r=p;

11

while (r!=NULL) { printf("%d ",r->inf); r=r->leg_d; } printf("\n"); } int main() { nod *p=NULL; int x,i; printf("dati numerele din lista\n"); scanf("%d",&x); p=nod0(x); scanf("%d",&x); i=2; while(x!=0) { if (i<=3) p=adauga_d(p,x); else p=adauga_s(p,x); scanf("%d",&x); i++; } listare(p); return 0; }

n urmtorul exemplu este creat un arbore binar de sortare.


#include <stdio.h> #include <alloc.h> typedef struct { int inf; struct nod *stg,*dr; } nod; nod *un_nod(int x) { nod *a; a=malloc(sizeof(nod)); a->stg=NULL; a->inf=x; a->dr=NULL; return a; }

12

nod *inserare(nod *a,int x) { if (a) if (x<=a->inf) a->stg=inserare(a->stg,x); else a->dr=inserare(a->dr,x); else { a=un_nod(x); } return a; } nod *creare(nod* a) {int n; printf("dati numerele\n"); scanf("%d",&n); while (n) { a=inserare(a,n); scanf("%d",&n); } return a; } int main() { nod *a=NULL; a=creare(a); return 0; }

Bibliografie:

[1] Kernigan, B. W., Ritchie, D. M. (1988) The C Programming Language - Second Edition, , Prentice Hall. [2] Tudor, S. (2000) Informatic, manual clasa a X-a, Varianta C++, Editura L&S Infomat; [3] Tudor, S. (2000) Informatic, manual clasa a XI-a, Varianta C++, Editura L&S Infomat;

13

You might also like