Newsgroup: it.comp.lang.delphi
Titolo: Oggetti, funzioni e memoria allocata

Ciao a tutti,
perdonate se la domanda e' banale, ma non e' molto tempo che mi diletto con
questo linguaggio e non ho trovato nulla di utile nei messaggi precedenti.
Lo scenario:
Delphi 6 PE
Applicazione console
in una unit ho una funzione globale definita grosso modo cosi'
function ListFromStr(delim: string; fullstr: string): TStringList;
var
    TempList: TStringList;
begin
    TempList := TStringList.Create;
    //[...] codice che popola la lista cercando i delimitatori passati
    Result := TempList;
    //o anche Result.Assign(TempList), stesso problema...
end;
il problema:
il tutto funziona ma, come vedete, non ho messo TempList.Free al termine
della funzione, dato che questo causa una violazione di accesso non appena
il codice chiamante accede alla variabile ottenuta dalla funzione...
ovviamente non avendo invocato il distruttore, le numerose chiamate che
faccio a questa routine tendono a causare una (piccola) perdita di memoria.
Sulla guida c'e' uno scarno riferimento sull'utilizzo a "breve e a lungo
termine" (ovvero variabile locale che viene creata e distrutta oppure
variabile che viene tenuta in vita fino al termine dell'applicazione) ma
niente di esplicito riguardo a oggetti creati da una funzione e restituiti
come risultato; per il momento ho aggirato la questione passando la lista
per riferimento invece che come risultato, ma mi piacerebbe capire qual'e'
il modo corretto di procedere in questi casi...
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

function ListFromStr(delim: string; fullstr: string; VAR AList:
TStringList): integer;
begin
  AList.Clear;
     //[...] codice che popola la lista cercando i delimitatori passati
     Result := AList.Count
 end;
Bye
AS

 ha scritto nel messaggio
news:acdnur$2qo2$1...@newsreader1.mclink.it...

come accennavo nel messaggio precedente, avevo gia' optato proprio per
questo sistema.
Per il momento la cosa non e' che mi turbi piu' di tanto, solo volevo
capire, anche per il futuro, per se c'e' un modo pulito per utilizzare una
istanza di oggetto direttamente come risultato di funzione...
Grazie comunque


 istanza di oggetto direttamente come risultato di funzione...
mah penso che l'unico modo sia chiamare il free del risultato..
StringList = funzione(bla bla); // la funzione crea l'oggetto
<usa l'oggetto>
StringList.free;

 il codice chiamante accede alla variabile ottenuta dalla funzione...
Non e' questo il modo migliore per ottenere una TStringList da
una funzione.  Riscrivi il tutto nel modo seguente:
procedure GetList(L: TStringList);
begin
  L.Clear;
  L.Add('pippo');
  L.Add('paperino');
  L.Add('pluto');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  L: TStringList;
begin
  L := TStringList.Create;
  try
    GetList(L);
    ShowMessage(L.Text);
  finally
    L.Free;
  end;
end;
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 function ListFromStr(delim: string; fullstr: string; VAR AList:
La keyword "VAR" non e' necessaria.


 una funzione.  Riscrivi il tutto nel modo seguente:
D'accordo, grazie a tutti, a questo punto sono a posto con quello che avevo
gia' corretto.
Mi confermi quindi che, come criterio generale, la via piu' indicata per
restituire un oggetto creato dinamicamente e popolato da parte di una
procedura e' sempre quella di passarlo come parametro invece che come
risultato di funzione ?


 risultato di funzione ?
Se non c'e' nessuno che si occupi di liberare i tuoi oggetti,
e' sempre meglio inserire nello stesso contesto allocazione e
liberazione della memoria.  In ogni caso, anche il codice 
seguente funziona:
function GetList: TStringList;
begin
  Result := TStringList.Create;
  try
    Result.Add('pippo');
    Result.Add('paperino');
    Result.Add('pluto');
  except
    FreeAndNil(Result);
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  L: TStringList;
begin
  L := GetList;
  if Assigned(L) then
  begin
    ShowMessage(L.Text);
