Sunteți pe pagina 1din 5

program unu;

var x: ^integer; { pointer la integer }

procedure P;
var y: integer; //y se aloca pe stiva
begin
y := 7;
x := @y; { adresa lui y } //in C ar fi echiv cu x=&y.
end;

begin;
P;//la iesirea din P var.y este dealocata !!!!
writeln(x^); //echiv in C cu *x - AICI SE MANIFESTA EROAREA LOGICA “DANGLING
REFERENCE” !!!!!
end;

program doi;
var x: ^integer; { pointer la integer } //compilatorul atribuie un nume de tip intern = TD02

procedure P;
var y: ^integer; //compilatorul atribuie un nume de tip intern = TD03
begin
new(y); //echiv in C cu y=malloc(int);
y^ := 7; //variabilei dinamice referita de y ii atribui valoarea 7
x := y; // SYNTAX ERROR !!!!!!!!!! TYPE MISMATCH ! pt ca “^INTEGER” NU
este un nume de tip ci O EXPRESIE DE TIP !!!!
end;

begin;
P; //y se dealoca la iesirea din P, DAR VARIABILA DINAMICA y^ ESTE IN CONTINUARE
ALOCATA IN HEAP !!!
writeln(x^); //x^ adreseaza variabila dinamica din heap si acum NU se mai manifesta dangling
reference !!
end;
Solutii pentru evitarea situatiei de syntax error:

program doi_solutia1;
type pint = ^integer;

var x: pint;

procedure P;
var y: pint;

begin
new(y);
y^ := 7;
x := y;
end;

begin;
P;
writeln(x^);
end;

program doi_solutia2;
var x: ^integer;

procedure P;
var y: ^integer;

begin
new(y);
y^ := 7;
x := @y^;//am transformat o atribuire de gen var:=var in var:=expresie !!!
{ dispose(y); – daca ar aparea aici, ar fi din nou dangling reference mai jos ! }
end;

begin;
P;
writeln(x^);
end;
a) char* s; //s este o VARIABILA de tip pointer la caracter
...
gets(s); //citeste de la tastatura un string pana la ENTER ! – ca sintaxa e totul ok
in schimb avem aici o EROARE LOGICA !!! …pt.ca NU s-a alocat SPATIU de memorie pt string-ul
punctat de s !! (s-a alocat spatiu pt s insa NU si pt string-ul intentionat a fi citit !!!)
...

b) char* s;
...
s = "abcd"; //s va primi valoarea adresei de inceput a constantei sir de char “abcd” ...
// Corect SI sintactic SI logic !!
…………
s = malloc(...); //ok si sintactic si logic !! ...
//correct amandoua sintactic ! (pt ca se atribuie o adresa in ambele cazuri);

c) char s[10]; //s este adresa de inceput a tabloului s, DAR s NU este o VARIABILA de TIP POINTER,
ci O CONSTANTA DE TIP POINTER !!!
...
gets(s); //correct sintactic, eroare logic apt stringuri mai lungi de 10 caractere !!!
...
s = malloc(...); //SYNTAX ERROR !! deoarece s NU poate fi L-value fiind O CONSTANTA !!!!
(aici ar fi echiv cu ceva de genul 7=expresie/valoare !!!)

d) char s[10];
...
s = "abcd"; ////SYNTAX ERROR !! deoarece s NU poate fi L-value fiind O CONSTANTA !!!! (aici
ar fi echiv cu ceva de genul 7=expresie/valoare !!!)

e) char s[ ] = "abcd"; //este correct !! – este vorba despre o asa numita situatie “syntactic sugar” …
={‘a’,’b’,….’\0’}….

int f(char* s);…. {…s=malloc()…} – PERFECT CORECT !!!!

DAR…. Daca… apelez cu f(v), unde char v[25], VOM OBTINE SYNTAX ERROR LA APEL !!!!!

Alte studii de caz:

1) char* f(...) { ... char s[15]; ... return s; }


Daca folosim f sub forma s22=f(a,b), unde char* s22, s22 va fi atribuita cu o valoare de tip adresa
care puncteaza pe stiva intr-o zona deja DEALOCATA!!!!!! Aceasta situatie va provoca
DANGLING REFERENCE !!!!!!
SOLUTIA ?.... static char s[15] !!!! – declarative care provoaca ALOCAREA lui s NU pe stiva
CI in GDS (segmentul global de date)…

2) char* f(...) { char* s; gets(s); ... return s; } – aceeasi eroare de tip DANGLING REF ca mai sus !!
(mai exact este similara cu a)…!!!!)

Solutia: char*s; s=malloc(500); gets(s)….. acum NU mai avem dangling reference !!!!

Exemplu care combina cele 2 reguli (asupra pointerilor si asupra tablourilor):

Un specificator const va modifica intotdeauna declaratorul care urmeaza imediat dupa el.

const char* step[3] = { “left”, “right”, “hop”}


// step este un tablou de 3 pointeri la siruri de caractere constante
// pointerii se vor putea modifica, sirurile de caractere NU

step[2] = “skip”; // ok – modifica pointer la const char


step[2][1] = ‘i’ ; // syntax error – nu se poate modifica sirul de caractere constant

char* const step[3] = { “left”, “right”, “hop”}


// step – tablou de pointeri constanti la siruri de caractere modificabile
// elementele tabloului sunt const

step[2] = “skip”; // syntax error – nu se poate modifica un pointer constant


step[2][1] = ‘i’ ; // ok – se modifica sirul de caractere punctat de un pointer constant

const char* const step[3] = { “left”, “right”, “hop”}


// step este un tablou de 3 pointeri constanti la siruri de caractere constante

step[2] = “skip”; // syntax error – nu se poate modifica un pointer constant


step[2][1] = ‘i’ ; // syntax error – nu se poate modifica sirul de caractere constant