How can i return a TStringList from a function without passing it as a parameter.
Take a look at this example:
function GetStrings(Value :String) :TStringList;
var
StrList :TStringList;
begin
// Here i will create StrList
StrList := TStringList.Create;
{**
codes....
}
// Here i will free the StrList
StrList.Free;
Result := StrList; // We cannot write this statement after freeing
the StrList nor i can exit this function without freeing the
// StrList because this will create a live pointer everytime the func is
called
end;//func
Note : I don't want to have one of the parameters of the function of type (var StrList: TStringList).The function should be an independent function.
Regrards
Anand
Anand <ana...@novatechsoftware.com> skrev i en nyhedsmeddelelse:3898D3E8...@novatechsoftware.com...
Your own proposal is not healthy, IMO.
--
Greg Lorriman
Handy, free utils at http://www.lorriman.demon.co.uk
For tiny setups see http://inner-smile.com/dl_inf.htm
and if you go for it then mention me.
"Anand" <ana...@novatechsoftware.com> wrote in message
news:3898D3E8...@novatechsoftware.com...
First, please do not post in HTML - it is against the forum guidelines.
If you are returning an object from a function, it is then the caller's
responsibility to free it, not the function itself. Also you do not need
to use a local variable, e.g:
function GetStrings(Value :String) :TStringList;
begin
Result := TStringList.Create;
{**
codes.... Result.Add('a string') etc
}
end;//func
Mike Orriss (TeamB)
(Unless stated otherwise, my replies relate to Delphi 4.03/5.00)
(Unsolicited e-mail replies will most likely be ignored)
IMO, you would be far better off having the caller create the TStringList
and pass it as an argument to be filled. This allows the caller to have
fine control over the creation and freeing of the object.
function GetStrings(AList: TStrings): boolean;
begin
Result := false;
// fill the list here
// if everything is o.k. then:
Result := true;
end;
when you call it:
var
myList: TStringList;
begin
myList := TStringList.Create;
try
if GetStrings(myList) then begin
// manipulate the list here.
end;
finally
myList.Free;
end;
end;
===
Regards
Ralph (TeamB)
===
You can, just as your code example shows. But you can't if you don't want
to return live pointers. In that case you'll have to use a parameter.
--
Rudy Velthuis
Yes, agreed.
Best thing is (like you propose, I think), to only have a function that
fills the list. Let the user create and/or free the stringlist.
And declaring the parameter as TStrings instead of TStringList will make
the function also accept other lists like the Items of a Listbox or the
Lines of a Memo.
--
Rudy Velthuis
function GetStrings(Value :String) :TStringList;
begin
Result:=TStringList.Create;
{**
codes....
}
end;
Use it so
procedure DoSomething;
var StrList:TStringList;
begin
StrList:=GetStrings('Blaa-blaa-blaa');
try
// do something with strlist...
finally
StrList.Free; // free the stringlist created by GetStrings!
end;
end;
HTH
ain
Note : I don't want to have one of the parameters of the function of type
(var StrList: TStringList).The function should be an independent function.
>>
The complications into which your code goes show why it is not sound to have
a function return a new object. It is easy to fix your function, but the
confusion will just pop up at the caller level. It's so much easier to have
one single place that both creates and frees an object -- unless it's a
component with an owner -- that doing otherwise will, 99% of the time, just
be a way to generate trouble.
Anyhow... your code returns the address of an object (strList) that has
already been freed. This is hardly going to be helpful to the caller! The
"fix" to do what you say you want is merely --
function GetStrings(Value :String) :TStringList;
begin
result := TStringList.Create;
try
{**
codes....
}
except
result.free;
result := nil;
raise;
end;
end;//func
If you want the function to return a TstringList, without getting one from
the caller first, then, obviously it has to be a new TstringList. There will
be no dangling pointers or whatever. Only, there will be a responsibility
for the *caller* to free the list once done with it. --
myList := getStrings(myString);
try
doLotsaStuff(myList);
finally
myList.free;
end;
If the caller for some reason calls getStrings as a procedure --
getStrings(myString);
then the resultant object will remain on the heap, unreachable, until the
application exits.
PhR