Newsgroup: it.comp.lang.delphi
Titolo: Funzione

Ciao,
ho scritto questa piccola funzione che restituisce una StringList.
Mi sorge pero' un dubbio: Se creo la stringlist con TStringList.Create;
poi non devo liberare le risorse con un free?
Perche se ci provo, (vedi penultima riga) mi da errore....
Ave
 Fabio
function ParsePar(SQLtext:String):TStrings;
var i      : integer;
    trigger: boolean;
    sPar   : String;
    ParList: TStrings;
begin
 ParList := TStringList.Create;
 trigger := false;
 for i:=0 to length(SQLTExt) do
 begin
    if SQLtext[i] = '{' then
     trigger := true;
    if SQLtext[i] = '}' then
       begin
          trigger := false;
          sPar := sPar + SQLtext[i];
          ParList.Add(sPar);
          sPar:='';
       end;
    if trigger then
       sPar := sPar + SQLtext[i];
 end;
 Result := ParList;
 //ParList.Free;
end;

Perche se ci provo, (vedi penultima riga) mi da errore....
Postalo.
Morde

le risorse delle variabili e gli oggetti creati in una funzione hanno come
scope e lifetime quello della funzione, per cui vengono disallocate quando
termina l'esecuzione :
non devi fare il Free.
L'errore č dovuto al fatto che stai facendo il free di quello che dovrebbe
essere il result della funzione!
CIAOUX

Ciao!
In che senso? La funzione l'avevo scritta nel post precedente.... vedi
sopra.


 ha scritto nel messaggio
news:asi3vv$ao2$1...@newsreader.mailgate.org...

Grazie, capito tutto....

poi non devo liberare le risorse con un free?
Si`, ma il tuo codice e` sbagliato.
Se ti proponi di restituire una TStringList non devi liberare la
memoria nella funzione stessa, altrimenti non ha senso.
E` come se io ti chiedessi di andarmi a comprare le sigarette e tu mi
portassi il pacchetto vuoto, perche` intanto te le sei fumate tutte.
O scrivi:
procedure AggiungiStringa(S: String; L: TStringList);
begin
  L.Add(S);
end;
var 
  L: TStringList;
begin
  L := TStringList.Create;
  try
    AggiungiStringa('ciao', L);
  finally
    L.Free;
  end;  
end.
oppure scrivi qualcosa di diverso:
function CreaStringList(S: String): TStrings;
begin
  Result := TStringList.Create;
  Result.Add(S);
end;
var
  L: TStrings;
begin
  L := CreaStringList('ciao');
end.

 essere il result della funzione!
Sě questo č corretto. Distrugge l'oggetto che dovrebbe essere usato come
risultato.
Non sono sicuro d'altronde di quale errore riceva miyomo, ho provato la
funzione *senza usare* il Result e non mi ha dato problemi.
Probabilmente rivedrei l'organizzazione della funzione, creare un oggetto
all'interno che deve poi essere restituito per l'uso puň portare problemi di
memory leak prima o poi, o di AV.
ciao
Antonio

varia natura, questi vengono distrutti insieme all'oggetto TStringList ?
Come li aggiungi ad una TStringList questi "oggetti di varia natura" ?
La TStringList non viene deallocata, comunque, alla fine della
funzione.


  ABLS Team (
www.abls.it
)

 funzione.
Aggiungo stringa e oggetto con il metodo AddObject della TStringList.
Ovviamente non essendo deallocata e perdendo il riferimento alla stessa,
come hai giustamente sottolineato, perdi anche i riferimento agli oggetti
aggiunti.

in genere, x evitare casini di questo tipo, le funzioni che devono in
qualche modo processare una stringlist le strutturo in altro modo:
function MiaFunzione(AList: tSTringList): integer;
begin
  Result := 0;
  AList.Clear;
end;
In questo modo sposto la responsabilità della Free a chi richiama la
funzione:
procedure FaiQualcosa;
var
  l: TStringList;
begin
  l := TStringList.Create;
  try
    if MiaFunzione(l) = 0 then begin
        //usa la TStringlist
   end;
  finally
  l.free;
end;
Bye
A.


Ciao

 sempre se vengono creati all'interno della funzione
No! Vedi sopra.
Ciao

Reference (Var) alla funzione.
Vedi sopra, assolutamente no.
Le istanze, in Delphi, sono puntatori all'oggetto realmente presente
in memoria, quindi non serve passare per riferimento.

Credo di aver capito. Scusate ma...
c'č ancora qualcusa che non mi torna
Andrea hai detto che Delphi non gestisce la Garbage Collection ma per quanto
ne so questo non č vero.
Il mio dubbio nasce dalla lettura del libro D4 Developer's Guide di Teix .
Pach. Pag 31 (cap.2) di cui riporto qualche stralcio
1
"
Oltre alle AnsiString Delphi fornisce altri tipi che sono lifetime-managed.
Tra questi ci sono
i vettori dinamici, WideString, Variant, OleVariant, interface e
dispinterface.
"
2
"
Qualora si dichiari una variabile locale di tipo lifetime-managed il
procedimento č leggermente
piů complesso: innanzitutto il compilatore aggiunge del codice per
assicurarsi che la variabile
sia inizializzata a zero in fase di esecuzione della procedura o funzione.
In seguito il compilatore
genera un blocco try..finally per la gestione delle eccezioni, il quale
incapsula l'intero
corpo della funzione. Infine il compilatore aggiunge altro codice nella
parte finally del
blocco in modo tale da ripulire la variabile lifetime-managed
"
Ora non so se questo si possa dire per gli oggetti ma mi fido di quello che
mi dite.
Fatemi sapere


  ABLS Team (
www.abls.it
)

mi dite.
Quanto afferma il Teixeira-Pacheco non vale per gli oggetti e i tipi
"garbage-collected" a cui fa riferimento subiscono, in realta`, il
"reference counting".

 "reference counting".
Capito, solo che lì dice Garbage Collected e io mi sono fidato. In cosa
consiste la differenza?

Ok, capito. Grazie

consiste la differenza?
Il termine usato da Teixeira-Pacheco e` effettivamente fuorviante, ma
va interpretato; loro si riferiscono al concetto di "raccolta della
spazzatura" SOLO per ALCUNI tipi predefiniti, cosa che in realta` non
e` cio` che si intende per gc vera e propria.  In realta`, poi, loro
si riferiscono al contatore di riferimenti, che e` un modo di
recuperare l'uso di istanze ancora in piedi e non liberare quelle non
piu` utilizzate.  La garbage-collection e` generalmente applicata
verso quegli oggetti che vanno fuori dallo "scope" di utilizzo.
In Java, per esempio, si puo` far a meno di liberare le istanze degli
oggetti, in quanto ci pensa il garbage-collector a farlo.
In C++ non esiste gc, ma (data la natura dell'allocazione degli
oggetti, che puo` anche essere statica) si possono usare gli smart
pointers (tramite template auto_ptr) che sono in grado di "possedere"
della memoria e liberarla quando vengono distrutti. 

Grazie mille ! :)