Sunteți pe pagina 1din 12

Datele de tip static au caracteristici care limiteaz rezolvarea unor clase de

probleme. n primul rnd, spaiul de memorie aferent unor astfel de date se definete
i se rezerv la dimensiune maxim, prestabilit, ca spaiu propriu care nu poate fi
disponibilizat i nici mprit cu alte date, chiar dac, n momentul diverselor execuii
ale programului, nu este n ntregime utilizat (rezervare static sau la momentul
compilrii). n al doilea rnd, componentele structurilor statice ocup locuri
prestabilite n spaiul rezervat, determinate de relaia de ordonare specific fiecrei
structuri. n al treilea rnd, limbajul definete operaiile admise cu valorile
componentelor, potrivit tipului de baz al structurii, astfel nct numrul maxim i
ordinea componentelor structurii nu pot fi modificate. n aceste condiii, structurile
statice sunt dificil de utilizat n rezolvarea problemelor care prelucreaz mulimi de
date pentru care numrul i ordinea componentelor se modific frecvent n timpul
execuiei programului. Pentru astfel de situaii, limbajul PASCAL ofer posibilitatea
utilizrii datelor de tip dinamic, crora li se pot aloca i elibera zone de memorie pe
parcursul execuiei programului.


1.1 Lucrul cu adrese n Pascal


Adresarea memoriei se realizeaz prin registre ale unitii centrale, care au
capacitatea de un cuvnt. La adresarea n modul real, pentru formarea unei adrese fizice
din spaiul de 1Mo este necesar folosirea a dou registre: de segment (segment), care
conine adresa de nceput a segmentului, numit i adresa de baz; de deplasare (offset),
care precizeaz distana la care se afl octetul adresat fa de nceputul segmentului.
Astfel, orice adres din memorie poate fi specificat n formatul segment:offset sau, n
ali termeni, baz:deplasare. ntruct deplasarea de 16 bii nu poate accesa o locaie de
memorie din afara domeniului 0..2
16
-1, rezult c dimensiunea maxim a unui segment
este de 64 Ko, restricie valabil pentru orice produs utilizat sub MS-DOS. Memoria
este mprit n paragrafe de cte 16 octei, iar fiecare segment ncepe la grani de
paragraf, adic de la o adres divizibil cu 16. ntr-un spaiu de 1Mo sunt 2
16
paragrafe,
ceea ce nseamn c adresa de nceput a unui segment, corespunznd unui numr de
TIPURI DINAMICE DE DATE
LUCRUL CU ADRESE
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
paragraf, poate fi reprezentat ca o valoare pe 16 bii. n calculul adresei fizice pe
20 bii, se aplic urmtoarea relaie: segment*16+offset, unde segment i offset
desemneaz coninutul registrelor de segment (un numr de paragraf), respectiv de
deplasare. Adresele din segmentul curent se numesc apropiate (near), iar cele din afara
acestuia sunt ndeprtate (far). Accesul la o adres apropiat presupune doar
schimbarea coninutului registrului de deplasare, n timp ce pentru o adres ndeprtat
trebuie schimbat att valoarea registrului de segment, ct i a celui de deplasare.
n unitatea System sunt definite funciile Seg(Var x):WORD, Ofs(VAR
x):WORD care furnizeaz adresa de segment i deplasarea variabilei, procedurii sau
funciei x. n Pascal exist tipul de date pointer, memorat pe dou cuvinte, n care
cuvntul superior (high) conine partea de segment, iar cuvntul inferior (low) pe cea de
deplasare asociate unei adrese. Pentru a se putea exemplifica modul de lucru cu
adrese, se precizeaz faptul c: tipul pointer se definete prin construcia de forma
^tip; adresarea indirect a unei variabilei se definete prin construcia identificator^;
referirea adresei unei variabile se definete prin construcia @identificator.
Programatorul trebuie s fac distincie ntre adresa i coninutul unei
variabile, precum i ntre adresarea direct i cea indirect. n exemplul de mai jos,
liniile surs numerotate de la 1 la 8 se genereaz urmtoarele tipuri de adresare: 1, 2,
4:adresare direct pentru ambii operanzi i lucru cu coninut; 3: adresare direct
pentru pa i a, lucru cu coninut pentru pa i cu adresa a; 5: adresare direct pentru c
i indirect pentru pa, lucru cu coninut; 6, 7, 8: adresare indirect i lucru cu
coninut. De remarcat c pa este de tip pointer, pa^ este de tip REAL iar @a este
adresa a (are configuraie de pointer).
n sintaxa @identificator, identificator se refer la o variabil, procedur sau
funcie. Efectul referirii @identificator este similar celui obinut prin funcia Addr
definit n unitatea System astfel: Addr(VAR x):pointer, unde x este variabil,
funcie sau procedur. Folosirea referirii identificator^ presupune existena unei
adrese valide n variabila identificator.

Exemplu:
1.1.
VAR a,b,c:REAL; {Se rezerv cte 6 octei pentru fiecare variabil}
pa,pb:^REAL; {Se rezerv cte 4 octei pentru fiecare variabil}
BEGIN
a:=20; {Se atribuie valoarea 20 variabilei de adresa a} 1
b:=a; {Se atribuie variabilei de adresa b, coninutul variabilei
de adresa a} 2
pa:=@a; {Se atribuie variabilei de adresa pa, adresa a} 3

pb:=pa; {Se atribuie variabilei de adresa pb, coninutul variabilei de
adresa pa} 4
c:=pa^; {Se atribuie variabilei c, coninutul variabilei a crei adres
este memorat n pa; aceasta este adresare indirect prin pa.
Lui c i se atribuie coninutul lui a (20)} 5
Tipuri dinamice de date. Lucrul cu adrese
WriteLn( 'Valoarea ',pb^:10:2,');
{Se scrie continutul variabilei a carei adresa este n pb } 6
WriteLn( 'Adresa fizica a lui A : ,seg(pb^),':',ofs(pb^));
{Se scrie adresa a, sub forma segment:deplasare} 7
WriteLn( 'Adresa fizica a lui PB:',seg(pb),':',ofs(pb));
{Se scrie adresa pb, sub forma segment:deplasare} 8



1.2 Structura memoriei la execuia unui program


Dup ncrcarea programului executabil, memoria aferent lui se structureaz
n urmtoarele regiuni (segmente): segmentul prefix program, regiunea de cod,
segmentul de date, stiva i zona heap (figura 1.1). Pentru adresarea acestora, unitatea
central de prelucrare folosete registre specializate (tabelul 1.1), la unele dintre ele
existnd acces direct (vezi tipul Registers din unitatea DOS, anexa 1) sau indirect din
programe Pascal.

Tabelul 1.1 Registre de segment /deplasare i funcii standard asociate
Tipul segmentului Registrul de
segment
Registrul de
deplasare
Seg:Ofs
Segment de cod CS (CSeg) IP CS:IP
Segment de date DS (DSeg) SI DS:SI
Segment de stiv SS (SSeg) SP (SPtr) SS:SP (SSeg:SPtr)
Observaie: Cseg, DSeg, SSeg, SPtr sunt funcii de tip WORD, nu au parametri i
sunt definite n unitatea System.

Segmentul prefix al programului (PSP) este o zon de 256 de octei constituit
de MS-DOS la ncrcarea n memorie a fiierului de tip .EXE. El conine informaii
necesare sistemului de operare pentru a transfera controlul ctre program, respectiv
pentru a returna controlul ctre sistemul de operare la ncheierea execuiei acestuia.
Adresa de segment este memorat n variabila public PrefixSeg, de tip WORD,
definit n unitatea System.
Regiunea de cod este constituit din mai multe segmente de cod: unul
corespunznd programului principal, respectiv cte unul pentru fiecare unitate referit n
program. Primul segment de cod este cel asociat programului principal, urmat de cele
ale unitilor, n ordinea invers specificrilor din clauza USES. Ultimul segment de
cod, introdus implicit n orice program executabil, corespunde unitii System, care
conine biblioteca de subprograme standard referite la momentul execuiei (Run-time
library). n absena clauzei USES, zona de cod va conine dou segmente: cel al
programului principal i cel al unitii System. Codul poate fi mprit ntr-un numr
oarecare de segmente, singura limitare fiind dat de memoria disponibil. Registrul CS
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
conine adresa de start a instruciunilor programului, iar registrul IP (registru pointer al
instruciunilor) precizeaz adresa urmtoarei instruciuni de executat. Programele Pascal
nu au acces la registrul IP, dar valoarea curent a registrului CS poate fi obinut cu
funcia CSeg. Adresa de nceput a zonei de cod este CSeg:0000. Coninutul registrului
CS se poate modifica pe parcursul execuiei, depinznd de faptul c instruciunile
executate sunt din programul principal sau din una dintre uniti.

Segment cod program principal

(Limita superioar a memoriei RAM convenionale)
HeapPtr
HeapOrg
SSeg:SPtr
SSeg:0000
DSeg:0000
CSeg:0000
PrefixSeg:0000
Heap
Stiva
Date
Cod
Zona neutilizat n heap
Zona neutilizat n stiva
Variabile globale
Constante cu tip
Unitatea System
Uniti specificate n
clauza USES
Exemplu:
USES Crt,A,B,C;
Segment cod Crt
Segment cod A
Segment cod B
Segment cod C
Program Segment Prefix (PSP)
Variabile dinamice curent alocate n heap
Date nregistrate n stiva
Coninut
fiier
.EXE

Fig. 1.1 Harta memoriei la execuia unui program Pascal

Segmentul de date este unic i conine constantele cu tip urmate de variabilele
globale. Atunci cnd necesarul de memorie pentru datele interne depete 64Ko,
trebuie s se recurg la folosirea unor tehnici adecvate (memorarea datelor n heap sau
pe medii externe, folosirea compactrii etc.). Registrul DS conine adresa de nceput a
segmentului de date i nu se modific pe parcursului execuiei. SI reprezint registrul
index al sursei, folosit pentru a puncta (a indexa) o dat n cadrul segmentului de date.
Pentru instruciunile asupra irurilor de caractere, registrul SI puncteaz pe operandul
surs, n timp ce un alt registru, index al destinaiei (DI), puncteaz operandul
destinaie. Funcia DSeg returneaz valoarea curent a registrului DS. Registrele SI i
DI pot fi accesate indirect, printr-un apel la o ntrerupere. Adresa de nceput a
segmentului de date este DSeg:0000.
Tipuri dinamice de date. Lucrul cu adrese
Segmentul de stiv, ca i cel de date, poate avea maximum 64Ko, reducn-
du-se la unul singur. Stiva este folosit n lucrul cu subprograme pentru memorarea
parametrilor formali, variabilelor locale i adreselor de revenire. Registrul SS conine
adresa de nceput a stivei i nu se modific pe parcursul execuiei. Registrul pointer al
stivei (SP) precizeaz deplasarea curent n cadrul stivei. Funcia SSeg returneaz
valoarea registrului SS, iar SPtr returneaz valoarea curent a registrului SP. n cadrul
stivei, alocarea spaiului se face ncepnd de la adrese mai mari spre adrese mai mici.
Adresa curent este definit de SS:SP sau, conform celor precizate anterior, de
SSeg:SPtr.
Zona variabilelor dinamice poate corespunde ntregii memorii convenionale
a calculatorului, rmas disponibil dup ncrcarea programului. n heap se memoreaz
variabilele dinamice, buffer-ele pentru structuri de reacoperire i pentru lucrul n modul
grafic. Adresa de nceput a zonei heap este dat de variabila public HeapOrg, iar
adresa curent este dat de variabila HeapPtr, ambele de tip pointer, definite n unitatea
System. Alocarea variabilelor ncepe de la adrese mai mici ctre adrese mai mari,
spaiul maxim ce poate fi alocat unei variabile neputnd depi 64Ko (strict riguros,
65520 octei), ca urmare a limitrilor impuse mecanismului de adresare a memoriei.
Dup modul lor de funcionare, stiva i heap-ul pot fi asimilate cu dou stive aezate
spate n spate.
Programatorul poate controla repartizarea memoriei disponibile ntre stiv i
heap n faza de execuie cu directiva de compilare {$M}, care are urmtoarea form
sintactic:
{$M StackSize,HeapMin,HeapMax}
StackSize trebuie s fie un ntreg din domeniul 1024 (1Ko) la 65520 (64 Ko),
prin care se specific mrimea segmentului de stiv. HeapMin i HeapMax specific
dimensiunea minim, respectiv maxim a heap-ului, teoretic cu valori ntre 0 i 640 Ko.
Riguros, HeapMin poate avea valori de la 0 la 655360, iar HeapMax trebuie s fie n
domeniul de la HeapMin la 655360. Valorile implicite pentru aceti parametri de
alocare sunt {$M 16384,0,655360}.
Rezult c dimensiunea implicit a stivei este de 16 Ko, iar zona de heap se
extinde, teoretic, n tot spaiul rmas liber n memoria convenional. Practic, din
dimensiunea de 640 Ko trebuie sczut, pe lng spaiul ocupat de programul nsui, cel
corespunztor componentelor sistemului de operare rezidente n memorie pe parcursul
execuiei.

1.3 Tipuri dinamice de date


n Pascal se opereaz cu dou tipuri de date dinamice - referin i pointer -
primele fiind "cu tip" iar celelalte "fr tip".
Tipul referin are sintaxa: tip_referin=^tip_de_baz;. Simbolul ^ are
semnificaia de "indirect". Datorit asocierii cu un tip de baz, variabilele tip_referin
se mai numesc i variabile cu referin legat. La compilare, pentru astfel de variabile,
se vor rezerva n segmentul de date dou cuvinte i la referirea lor se vor genera
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
instruciuni cod main conform tipului de baz, dar cu adresare indirect. nainte de
referire, n variabilele de tip_referin trebuie s se ncarce adresele variabilelor de tipul
tip_de_baz. Declararea unui tip referin permite referirea anterior declarrii tipului de
baz. Astfel, urmtoarea secven de declarri este corect: TYPE pointer_a=^vector;
vector=ARRAY[1..20] OF REAL;
Construcia sintactic a referirii unei variabile dinamice depinde de
caracteristicile tipului su de baz: este de forma identificator^ n cazul tipurilor
nestructurate sau celor structurate care permit referirea global (STRING, RECORD i
SET); conine prefixul identificator^, urmat de elementele specifice modului de
referire a componentelor, n cazul tipurilor structurate care permit referirea pe
componente (ARRAY, STRING i RECORD). Aceste posibiliti de referire sunt
ilustrate n programul Alocare_dinamic_1.
Tipul pointer este desemnat prin cuvntul rezervat pointer. Variabilele de tip
pointer pot fi denumite variabile cu referin liber, deoarece pot fi folosite la
memorarea adreselor pentru variabile de orice tip. Tehnica de lucru cu astfel de variabile
este asemntoare celei prezentate la tipul referin. Utilizarea efectiv presupune i n
acest caz o asociere explicit cu un anumit tip de baz, dar soluia folosit este diferit.
La tipul referin, asocierea se face prin declarare, iar n cazul tipului pointer asocierea
se realizeaz la utilizare, prin diverse tehnici. O posibilitate este asigurat de referina
typecasting (transfer de tip), care are forma general: tip(variabil), unde tip este un tip
standard sau declarat anterior de utilizator iar variabil poate fi cu/fr tip sau o
referin prin pointer, de forma variabil_pointer^.
Din punct de vedere fizic, variabilele de tip referin_legat i pointer
memoreaz adrese sub forma segment:offset. De aceea, n limbajul curent de
specialitate, ambele tipuri se definesc prin termenul pointer. Urmtorul exemplu
evalueaz expresia e:=a+b, folosind adresarea indirect pentru toate variabilele (a i e
prin referin_cu_tip iar b prin pointer):

VAR
a,b,e:REAL;
pa,pe:^REAL;
pb:POINTER;
BEGIN
pa:=addr(a); pb:=@b; pe:=@e;
Write(A=); ReadLn(pa^);
Write(B=); ReadLn(REAL(pb^));
pe^:=pa^+REAL(pb^);
WriteLn(E= ,pe^:8:2))
END.

Variabilele pointer (referin sau pointer) pot fi puse n relaie cu operatorii = i
< >. Dou variabile vor fi egale dac au componentele segment, respectiv offset egale.
De remarcat faptul c dou variabile de tip pointer care indic aceeai adres pot fi
neegale, deoarece le difer componentele. Variabilele pointer pot fi folosite n atribuiri.
Att n relaii ct i n atribuiri sunt definite urmtoarele clase de compatibilitate: tipul
referin este compatibil cu orice alt tip dinamic; dou variabile de tip referin sunt
compatibile dac sunt de acelai tip.
Observaie: pa i pb nu sunt de acelai tip dac sunt declarate astfel: pa:^real; pb:^real.
Tipuri dinamice de date. Lucrul cu adrese
Ele sunt de acelai tip dac sunt declarate astfel: pa,pb:^real.
Este definit o constant simbolic (nil) cu semnificaie de valoare nul a
tipului dinamic (valoarea nil nu puncteaz o zon de memorie).



1.4 Utilizarea zonei heap


Noiunea de dinamic este strns legat de utilizarea zonei de memorie heap
(dei tipul dinamic poate fi asociat variabilelor memorate n orice component a
memoriei principale). n unitatea System sunt definite urmtoarele variabile de tip
pointer, care pot fi folosite n gestionarea zonei heap: HeapOrg, HeapPtr, HeapEnd,
HeapError, FreeList.
HeapOrg puncteaz pe adresa de nceput a zonei heap, iar HeapEnd d adresa
de sfrit a heap-ului. HeapPtr conine urmtoarea adresa disponibil din heap. Ea este
variabila prin care se gestioneaz fiecare nou alocare, punctnd pe prima adres
disponibil din heap. Toate procedurile de alocare (New, GetMem, Mark) lucreaz cu
aceast variabil. HeapError corespunde adresei rutinei de tratare a erorilor de alocare
pentru variabile dinamice. FreeList servete la gestiunea blocurilor devenite libere n
interiorul heap-ului, punctnd pe primul bloc liber n heap, care puncteaz pe al doilea
.a.m.d. Ultimul bloc liber puncteaz pe vrful heap-ului, adic pe locaia dat de
HeapPtr, asigurndu-se astfel posibilitatea realocrii acestor spaii. Dac n interiorul
heap-ului nu exist blocuri libere, atunci FreeList va fi egal cu HeapPtr.
De asemenea, n unitatea System sunt definite o serie de proceduri i funcii
care pot fi utilizate n lucrul cu variabilele dinamice. Procedurile GetMem(p,n),
FreeMem(p,n), respectiv New(p) i Dispose(p) se folosesc pentru a aloca/elibera un
bloc a crui adres este dat de variabila pointer sau referin, p.
Deoarece zona heap este limitat, iar alocarea i eliberarea dinamic
determin alternana unor zone libere cu cele ocupate, este necesar cunoaterea
spaiului disponibil i a spaiului contiguu maxim disponibil. n acest scop pot fi
folosite funciile (fr argumente, cu rezultat de tip LONGINT) MemAvail (pentru
spaiul total disponibil) i MaxAvail (pentru spaiul contiguu maxim disponibil).
Iniial, rezultatul furnizat de MemAvail corespunde dimensiunii totale a heap-ului, care
poate fi obinut i prin aplicarea formulei (Seg(HeapEnd^)-Seg(HeapOrg^))*16,
ntruct adresele de nceput i de sfrit ale heap-ului sunt exprimate ca numere de
paragraf. De asemenea, aceast dimensiune coincide iniial cu cea furnizat de funcia
MaxAvail, care precizeaz cel mai lung bloc de locaii de memorie contigue disponibile
n heap. Se poate determina dac spaiul disponibil este contiguu, pe baza expresiei
relaionale MemAvail = MaxAvail. Dimensiunea n octei ocupat de o variabil
poate fi obinut cu funcia SizeOf(VAR x):WORD, unde x este identificator de
variabil. Se poate stabili dac spaiul disponibil este acoperitor pentru o variabil de
un anumit tip, scriind o relaie de forma MaxAvail >= SizeOf (tip).
Alocarea i eliberarea zonelor pentru variabile referin_legat se face cu
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
procedurile New, respectiv Dispose, definite n unitatea System astfel: New(VAR
p:pointer), Dispose(VAR p:pointer). Procedura New rezerv n heap o zon de
memorie de lungime egal cu cea indicat de tipul de baz i ncarc n variabila p
adresa acestei zone.

Exemplu:
1.2.
VAR
px:^INTEGER; {La compilare se rezerva 4 octeti in segmentul de date}

BEGIN

New(px); {La executie se rezerva 2 octeti si se incarca adresa zonei rezervate in
px}
px^:=21; {Se memoreaza valoarea 21 in zona de tip INTEGER din heap}
Dispose(px); {Se elibereaza spatiul rezervat in heap}

De remarcat c exist dou niveluri de rezervare: static (corespunztoare lui
px) i dinamic (datorat procedurii New(px), care rezerv variabil n heap, n
conformitate cu tipul de baz). Din punct de vedere fizic, operaia realizeaz memorarea
n variabila p a valorii HeapPtr i avansarea acesteia din urm cu lungimea specific
tipului de baz. Dac nu exist o zon contigu disponibil de lungime mai mare sau
egal cu cea necesar, se genereaz eroare de execuie. Procedura Dispose elibereaz
zona alocat variabilei. Urmtorea alocare se poate face pe spaiul eliberat, dac este
acoperitor ca lungime. Fizic, se reface n HeapPtr valoarea de dinaintea alocrii prin
New.
n programul Alocare_dinamic_1 se ilustreaz prin exemple simple alocarea i
eliberarea spaiului din heap, precum i referirile globale i pe componente pentru
variabile dinamice ale cror tipuri de baz sunt nestructurate sau structurate. La execuia
programului, pe lng afiarea mesajelor care ilustreaz corectitudinea folosirii tehnicii
de lucru cu variabile dinamice, se remarc revenirea n final, dup eliberarea tuturor
zonelor alocate, la dimensiunea iniial a heap-ului.
Prin posibilitatea de generare a unor succesiuni de valori de acelai tip, de la
simpla alocare dinamic de spaiu pentru o singur valoare a unei variabile se poate
trece la realizarea unor structuri dinamice de date. Acest lucru este posibil pe baza
nlnuirii succesiunilor de valori, ca urmare a includerii la fiecare element al structurii a
dou pri: o parte de informaii, corespunznd valorii propriu-zise a elementului; o
parte de legtur, care va conine adresa urmtorului element.
Fr a se urmri, n acest context, abordarea problematicii implementrii
structurilor de date complexe (liste, stive, cozi, arbori binari etc.), n programul
Alocare_dinamic_2 se prezint realizarea unei liste nlnuite pentru memorarea n
heap a unui vector. Aplicaia are n vedere memorarea n heap a unui vector de mari
dimensiuni, cu elemente de tip ntreg. Pentru fiecare element se construiete o structur
de tip RECORD, n forma asociat tipului element. Pentru simplificare, se cere
utilizatorului s precizeze numrul total de valori i valoarea de start, elementele fiind
generate automat, ca numere ntregi consecutive. Dup construire se reia traversarea
Tipuri dinamice de date. Lucrul cu adrese
listei, cu afiarea pe monitor a elementelor vectorului.
Prin procedura New(leg) se va aloca o zon de memorie de dimensiunea unei
date de tipul element, iar n variabila de tip leg se va memora adresa de nceput a acestei
zone. Zona de memorie a crei adres este coninut n variabila de tip leg va fi referit
prin indirectare, folosind o construcie sintactic format din - sau ncepnd cu -
variabila de tip leg^.

PROGRAM Alocare_dinamica_1;
USES Crt;
TYPE
pv=^v;
v=ARRAY[1..100] OF INTEGER;
ps=^s;
s=STRING[120];
pm=^m;
m=SET OF CHAR;
pc=^CHAR;
pa=^a;
a=RECORD
nume:STRING[15];
nota:ARRAY[1..5] OF 1..10;
end;
VAR
legv:pv; legs:ps; legm:pm; legc:pc; lega:pa;
BEGIN
ClrScr;
WriteLn('Adresa de inceput heap: ',
Seg(HeapOrg^),':',Ofs(HeapOrg^));
Writeln('Adresa de sfirsit heap: ',
Seg(HeapEnd^),':',Ofs(HeapEnd^));
WriteLn('Valoare pointer heap: ',
Seg(HeapPtr^),':',Ofs(HeapPtr^));
WriteLn('Dimensiune totala heap: ',MemAvail);
{Rezultat echivalent: (Seg(HeapEnd^)-Seg(HeapOrg^))*16 }
WriteLn('Bloc maxim in heap: ',MaxAvail);
New(legv);
WriteLn('Memorie alocata in heap: ',SizeOf(legv^));
WriteLn('Memorie libera in heap: ',MemAvail);
legv^[1]:=1;
WriteLn('v[1]=',legv^[1]);
Dispose(legv);
WriteLn('Memorie libera in heap: ',MemAvail);
New(legs); legs^:='PASCAL';
WriteLn('Al treilea caracter din sir este ',legs^[3]);
New(legm); legm^:=['a'..'c'];
IF 'c' IN legm^ THEN Writeln('Litera "c" apartine multimii');
New(legc); legc^:=#65; Writeln('Caracter atribuit: ',legc^);
New(lega); lega^.nume:='POPESCU ION'; lega^.nota[2]:=10;
WriteLn('Studentul ',lega^.nume,' are nota ',lega^.nota[2], '
la disciplina a doua');
Dispose(lega); Dispose(legs); Dispose(legc); Dispose(legm);
WriteLn('Memorie libera in heap: ',MemAvail);
END.
Din analiza programului Alocare_dinamic_2 se pot desprinde cteva din
cerinele impuse programatorului n construirea i prelucrarea structurilor dinamice.
Astfel, pentru a face posibil traversarea ulterioar, se memoreaz n variabila de tip
referin inceput adresa primului element. La construirea unui nou element, inclusiv a
primului, cmpul de legtur urm (de tip referin) este iniializat cu valoarea nil; la
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
traversarea ulterioar, regsirea unei valori nil corespunde identificrii ultimului
element din list. Pentru toate elementele, ncepnd cu al doilea, construirea presupune
revenirea la elementul anterior, a crui informaie de legtur trebuie s puncteze pe
elementul nou construit. Aceast balansare este asigurat prin jocul variabilelor de tip
referin curent, respectiv urmtor.

PROGRAM Alocare_dinamica_2;
leg=^element;
element=RECORD
v:INTEGER;
urm:leg;
END;
VAR
inceput,curent,urmator: leg;
n,vi,i:INTEGER;
BEGIN
Write('Nr. de elemente si valoare de inceput: ');
ReadLn(n,vi);
New(inceput);
inceput^.v:=vi;
inceput^.urm:=nil;
WriteLn('S-a creat elementul 1 = ',inceput^.v);
curent:=inceput;
FOR i:=2 TO n DO
BEGIN
New(urmator);
urmator^.v:=curent^.v+1;
urmator^.urm:=nil;
WriteLn('S-a creat elementul ',i,' = ',urmator^.v);
curent^.urm:=urmator;
curent:=urmator
END;
i:=1;
curent:=inceput;
WHILE curent^.urm <> nil DO
BEGIN
WriteLn('v[',i,']: ',curent^.v);
curent:=curent^.urm;
Inc(i)
END;
Writeln('v[',i,']: ',curent^.v)
END.

Alocarea i eliberarea zonelor pentru variabile de tip pointer se realizeaz cu
procedurile GetMem, respectiv FreeMem, definite n unitatea System astfel:
GetMem(VAR p:pointer; l:WORD), FreeMem(VAR p:pointer; l:WORD). Efectul
acestora este asemntor procedurilor New i Dispose, cu precizarea c este necesar
specificarea lungimii, care nu poate fi dedus implicit, neexistnd un tip de baz. Un
exemplu simplu de folosire a variabilelor pointer din heap este ilustrat n programul
Alocare_dinamic_3.

PROGRAM Alocare_dinamica_3;
Tipuri dinamice de date. Lucrul cu adrese
VAR
p: POINTER;
BEGIN
GetMem(p,6);
REAL(p^):=5.25;
WriteLn(REAL(p^):4:2);
FreeMem(p,6)
END.

Relund exemplul propus prin programul Alocare_dinamic_2, trecerea la
folosirea variabilelor pointer presupune unele adaptri, ilustrate n programul
Alocare_dinamic_4. Din program se constat c aplicarea tehnicii de typecasting
permite att referirea global, ct i pe componente, ilustrat n acest caz pentru
cmpurile unui articol. Spaiul alocat la un apel al procedurii GetMem corespunde
dimensiunii articolului (6 octei).

PROGRAM Alocare_dinamica_4;
TYPE
element=RECORD
v:INTEGER; urm:POINTER;
END;
VAR
inceput,curent,urmator: POINTER;
n,vi,i : INTEGER;
BEGIN
Write('Nr. de elemente si valoare de inceput: ');
ReadLn(n,vi);
GetMem(inceput,6);
element(inceput^).v:=vi;
element(inceput^).urm:=nil;
WriteLn('S-a creat elementul 1 = ',element(inceput^).v);
curent:=inceput;
FOR i:=2 TO n DO
BEGIN
GetMem(urmator,6);
element(urmator^).v:=element(curent^).v+1;
element(urmator^).urm:=nil;
WriteLn('S-a creat elementul ',i,' =
'element(urmator^).v);
element(curent^).urm:=urmator;
curent:=urmator
END;
i:=1;
curent:=inceput;
WHILE element(curent^).urm <> nil DO
BEGIN
WriteLn('v[',i,']: ',element(curent^).v);
curent:=element(curent^).urm;
Inc(i)
END;
Writeln('v[',i,']: ',element(curent^).v)
END.

Ca alternative ale procedurilor New, GetMem, respectiv Dispose,
FreeMem, pot fi folosite procedurile Mark i Release, definite n unitatea System
astfel: Mark(VAR p:pointer), Release(VAR p:pointer). Procedura Mark
memoreaz n variabila p valoarea din HeapPtr, iar procedura Release depune n
Programarea calculatoarelor Tehnica programrii n limbajul Pascal
variabila HeapPtr coninutul variabilei p. Folosirea n pereche a procedurilor Mark
i Release ofer posibilitatea ca, dup diverse alocri, s se restabileasc valoarea
variabilei HeapPtr cu valoarea memorat prin Mark. Apelul Release(HeapOrg)
aduce HeapPtr pe nceputul zonei heap (elibereaz zona).
n exemplul urmtor, se memoreaz n y adresa de la un moment dat a lui
HeapPtr (fie ea a), se modific HeapPtr prin rezervarea a 12 octei (pentru x2, x3),
se reface coninutul lui HeapPtr cu adresa a, ceea ce nseamn c x3^ se rezerv la
aceast adres (n locul variabilei x2^).

VAR
x1,x2,x3.x4:^REAL;
y:POINTER;
BEGIN
New(x1); x1^:12;
Mark(y); {Memorarea valorii HeapPtr in Y}
New(x2); x2^:=10;
New(x3); x3^:=34;
Release(y); {Reincarcarea valorii din Y in Heapptr}
New(x4); x4:=46; {Se va memora peste valoare 10 din x2}