«Правильный» подход заключается в том, чтобы вы установили свои собственные правила для того, как вещи будут уничтожены. Хорошо создавать объекты в результате функции, но только если вы выполняете свои собственные строгие правила.
В вашем случае SomeFunction
имеет утечку памяти. Сначала вы создаете TStringList
, а затем, если какое-либо условие выполнено, вы создаете на своем месте еще один TStringList
, полностью игнорируя первый. Таким образом, утечка памяти.
DoSomething
не должен быть функцией, возвращающей список строк, если есть вероятность, что у вас уже есть один созданный. Вместо этого, просто сделать это процедура ...
procedure DoSomething(AList: TStringList);
begin
AList.Add(Something);
end;
После того, как вы сделаете это, то SomeFunction
должен выглядеть следующим образом:
function someFunction: TStringList;
begin
Result:= TStringList.Create;
if someConditionIsTrue then
DoSomething(Result);
//other code
end;
"В stringlists никогда не освобожденный"
I надеюсь, что это не по дизайну. Все, что вы создаете, должно быть свободным в какой-то момент, особенно если у вас есть функции, которые создают их результат. Единственное исключение - если вы создаете что-то, что живет в течение всего срока действия приложения, и даже тогда это крайняя распространенность, чтобы освободить их в любом случае.
На этой ноте, единственный раз, когда я когда-либо создать объект в результате функции, когда я герметизирующего несколько строк кода, которые иначе были бы дублируется много раз. Например, создание запроса.
Вместо того чтобы повторять этот код ...
Q:= TADOQuery.Create(nil);
Q.Connection:= MyDatabaseConnection;
Q.SetSomeOtherProperties;
... Я положил его в функцию ...
function CreateQuery: TADOQuery;
begin
Result:= TADOQuery.Create(nil);
Result.Connection:= MyDatabaseConnection;
Result.SetSomeOtherProperties;
end;
Тогда, я могу просто вызвать эту функцию всякий раз, когда мне нужно повторить этот код ...
Q:= CreateQuery;
Вы уже вызываете утечку памяти в первом примере кода, даже не используя его нигде. Сначала вы создаете экземпляр, затем полностью игнорируете этот экземпляр и создаете еще один на своем месте. –
Ваш код создает 2 экземпляра TStringlist, что приведет к утечке памяти. И тот, который возвращается некоторой функцией, будет отличаться в зависимости от значения 'someConditionIsTrue'. Ничего, вам не нужно. Создавать в doSomething. – MartynA
Нет «правильного» способа. Вам нужно разработать свою конвенцию о том, какая партия освобождает память ** и строго следовать ей. Кроме того, вам нужно следить за подсказками компилятора, это указывает на проблему с первым фрагментом. –