TStringlist as function result, minimal code sequence
How to return a Stringlist from a function has been discussed many time before. My code sequence version 1 is just a recap how to do it.
function GetStrings : TStringList;
begin
Result := TStringList.Create;
Result.Add('string A');
Result.Add('string B');
end;
procedure TForm1.Button1Click(Sender: TObject);
var stemp : tStringList;
begin
stemp := GetStrings;
MyListBox.items.addstrings(stemp);
stemp.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MyListBox.items.addstrings(GetStrings);
end;
is there any option to fix the memory leak in version2 with "no extra code", how dangerous is this approach at all, will this cause any failures if my stringlist is just a few string items, out of memory issues will not happen?
---------------------------------------------------------------------------------------------------------------
As others as mentioned, you need to add extra code to both the function and the caller in order to manage the TStringList
correctly to ensure it is always freed.
A better option is to not return a TStringList
at all, but rather to take in any TStrings
object the caller wants and just fill it in, eg:
procedure GetStrings(Strings: TStrings);
begin
Strings.BeginUpdate;
try
Strings.Add('string A');
Strings.Add('string B');
finally
Strings.EndUpdate;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetStrings(MyListBox.Items);
end;
--------------------------------------------------------------------------------------------------------------------------------------
If you are going to return a newly instantiated object from a function, there is a pattern for that. It goes like this:
function GetStrings: TStringList;
begin
Result := TStringList.Create;
try
Result.Add('string A');
Result.Add('string B');
except
Result.Free;
raise;
end;
end;
This function behaves just like a constructor. Either it returns a newly instantiated object, and passes ownership to the caller. Or it raises an exception, and tidies up before raising it.
If you use this pattern, then you need to do so in the same way as you would with an object instantiated by a constructor, using the well known pattern:
procedure TForm1.Button1Click(Sender: TObject);
var
temp: TStringList;
begin
temp := GetStrings;
try
MyListBox.Items.AddStrings(temp);
finally
temp.Free;
end;
end;
Now, as for your direct question:
is there any option to fix the memory leak in version2 with "no extra code", how dangerous is this approach at all, will this cause any failures if my stringlist is just a few string items, out of memory issues will not happen?
If you do return a newly instantiated object, then the caller can't avoid the responsibilities of ownership for that object.
Learn more about this article kindly follow this link
0 Comments
If you have any doubts, Please let me know