-
Тут как бы надо знать устройство дельфового менеджера памяти на более высоком уровне, чем его знаю я. Поэтому спрошу в сюда. вот код:
function GetSomeList: TStringList;
begin
Result := TStringList.Create;
end; далее я вызываю данную функцию, например
SomeListBox.Items := GetSomeList; теперь результат работы функции GetSomeList надо как-то уничтожить. Если сделать GetSomeList.Free - функция выполняется два раза, а это не оптимально, да и порой неудобно. Каким образом лучше реализовать? То есть мне просто надо сделать функцию, возвращающую стринглист и чтобы без утечки памяти.
-
сделай процедуру, которой передаешь созданный TStringList, потом его уничтожаешь, когда нужно.
-
Procedure FillStringList(p_theSL:TStringList);
Begin
.. заполняем
End;
Var
theSL:TStringList;
Begin
theSL:=TStringList;
Try
FillStringList(theSL);
...
Finally
theSL.Free;
End;
End; это - правильно
-
зачем создавать TStringList для св-ва TStrings если оно уже создано и используется в объекте
Procedure FillStringList(p_theSL:TStrings); Begin .. заполняем End;
FillStringList(SomeListBox.Items);
-
> Palladin © (09.02.09 08:04) [2] > theSL:=TStringList;
theSL:=TStringList.Create; Я не смеюсь, мало ли, чего недопонял :)
-
:) никто не застрахован от описек и недописек :)
-
> korneley © (09.02.09 08:13) [4]
Это не чистый дельфи, это Palladin Delphi Extension ®
-
> Palladin © (09.02.09 08:04) [2]
идею понял. так и сделаю ибо проще. спасибо. а все таки интересно, как ведет себя менеджер памяти. Вот когда я делаю так: SomeListBox.Items := GetSomeList; в SomeListBox.Items передается указатель на стринглист созданный функцией GetSomeList. Если например сделать так:
var
TempList: TStringList;
begin
TempList := GetSomeList;
try
SomeListBox.Items := TempList;
finally
TempList.Free;
end;
end;
если в TempList передается указатель на стринглист, созданный функцией GetSomeList, то при выполнении строки TempList.Free этот самый стринглист должен умереть. Я прав?
-
> 123-ий © (09.02.09 09:27) [7]
> Я прав?
Угу.
-
> 123-ий © (09.02.09 09:27) [7]
Абсолютно, но функций создающих и возвращающих объект какого то класса, нужно по возможности избегать. Все дело в том, что в процессе создания и/или инициализации этого объекта может произойти исключение и, в следствии этого утечка памяти. Например Function CreateMyObj:TMyClass;
Begin
Result:=TMyClass.Create;
Result.Prop1:=Value1; End;
Var
obj:TMyClass;
Begin
obj:=CreateMyObj;
Try
...
Finally
obj.Free; End;
End;
-
> Palladin © (09.02.09 08:04) [2] > Procedure FillStringList(p_theSL:TStringList); > Begin > .. заполняем > End;
Тогда даже лучше Procedure FillStringList(p_theSL:TStrings); Тогда туда можно будет передавать в том числе и Items от SomeListBox и не придется создавать временный, а потом из него копировать.
-
Именно в [3], по этому поводу, я и исправился, более внимательней прочитав вопрос )
-
> Palladin © (09.02.09 09:43) [11]
а, точно, не заметил, сорри.
-
А почему вопрос задан в потрепаться, а не в тематической?? вполне себе тематический вопрос, по-моему.
-
> Palladin (09.02.2009 9:41:09) [9]
Это можно легко исправить, немного переделав функцию, но смысла нет.
-
> KSergey © (09.02.09 09:45) [13]
на всякий случай. туда предпочитаю не лазить почему то. :)
> Anatoly Podgoretsky © (09.02.09 09:51) [14]
смысла то нет, а все тки расскажите. =) интересно
-
KSergey © (09.02.09 09:45) [13] Тут мастеров больше ))
-
> 123-ий © (09.02.09 10:03) [15] > смысла то нет, а все тки расскажите. =) интересно
А самому подумать? как подсказка - try/except
-
А я вот немного не пойму, пример в [0] был тестовый или взятый из "реальной жизни"? Просто зачем создавать промежуточный TStringList если он уже создан в SomeListBox? Может проще брать его оттуда и использовать? Зачем лишние затраты на создание класса и вызов Assign-а при присвоении?
-
> [0] 123-ий © (09.02.09 07:42) > GetSomeList.Free - функция выполняется два раза, а это не оптимально, да и порой неудобно.
Более того.... Неправильно, ибо память, выделенная в первом вызове, так и утекет в никуда....
-
> KSergey © (09.02.09 10:24) [17]
дошло уже. :)
> Rouse_ © (09.02.09 10:41) [18]
ну как сказать, просто есть один листбокс и несколько функций, которые должны его заполнять ибо разные функции заполняют его разными данными. собственно они заполняют даже не какойто один определенный заранее листбокс, а несколько. короче тут как раз катит вариант предложенный палладином.
> {RASkov} © (09.02.09 10:59) [19]
вот вот, оно и выглядело как то странно. действительно, если бы я сразу подумал, ведь вызвав эту функцию два раза, я два раза создам СтрингЛист, а уничтожится он только во второй раз.
-
> 123-ий (09.02.2009 10:03:15) [15]
Ввести кроме создания еще и обработку ошибок там же, при ошибке разрушать, если был создан и игнорировать разрушение в процем случае, наружу выдавать nil и возможно исключение.
-
> 123-ий (09.02.2009 11:09:20) [20]
Это глупо, если вызван два раза, то и разрушать должен два раза, каждый экземпляр.
-
> Anatoly Podgoretsky © (09.02.09 11:23) [21]
Угу, разрушать в функции создающей, это как гланды вырезать через другой проход.
Создание - конструктору, инициализация - в безопасном месте.
-
> ну как сказать, просто есть один листбокс и несколько функций, > которые должны его заполнять ибо разные функции заполняют > его разными данными
Ну так делай у каждой функции констатарный параметр в который приходит TStrings и пусть они этот TStrings и заполняют, какая разница что это будет, Items или руками созданный TStringList
-
Хм... немножко разьясню [24], а то начали в аське переспрашивать :) Есть к примеру много листов в которые выводятся данные, так-же есть к примеру 3 процедуры, каждая из которых заполняет листы своими специфическими данными. Как я вижу все это действо: не стоит городить огород с промежуточными TStringList, а стоит написать 3 процедуры вида: procedure FillListA(const Value: TStrings);
var
I: Integer;
begin
Value.Clear;
for I := 0 to Count - 1 do
Value.Add()
end;
procedure FillListB(const Value: TStrings)
procedure FillListC(const Value: TStrings)
После чего без всяких промежуточных листов вызываем необходимую нам на данным момент процедуру с тем листом, который нужно заполнить: FillListA(SomeListBox.Items); Вот как-то так...
-
> Rouse_ © (09.02.09 13:21) [25] > Хм... немножко разьясню [24], а то начали в аське переспрашивать :)
Это те, кто не смог прочитать [3] и [10]?! Нахрен на них время-то тратить??
-
:)))) и то правда
-
> Rouse_ © (09.02.09 12:55) [24]
дык я ж написал что так и сделаю в > 123-ий © (09.02.09 09:27) [7] , первая строчка =))
-
> Это те, кто не смог прочитать [3] и [10]?! Нахрен на них > время-то тратить??
Видимо не внимательно прочитал :)))) Пардоньте :)
-
> Видимо не внимательно прочитал :)))) Пардоньте :)
бывает =)))
-
> Palladin (09.02.2009 12:48:23) [23]
Ты вне темы - речь идет об разрушение в случае ошибки.
-
> Palladin © (09.02.09 09:41) [9] > Function CreateMyObj:TMyClass; > Begin > Result:=TMyClass.Create; > Result.Prop1:=Value1; // предположим, здесь возникает исключение > End;
И в чём проблема? function CreateMyObj: TMyClass;
begin
Result := TMyClass.Create;
try
except
Result.Free;
raise
end
end;
-
> Григорьев Антон © (09.02.09 16:28) [32]
В лишних телодвижениях, зачем нужно отслеживать в отдельном блоке try/except успешность назначения свойств, если гораздо логичней и понятней штатный вызов конструктора и уже далее в try/finally ассигнование свойств. Для себя же пишем. Не смущайте начинающих.
-
> Григорьев Антон © (09.02.09 16:28) [32] > И в чём проблема?
Проблемы нет, лишь обратили на это внимание автора, предполагалось, что до этого он и сам догадается до приведенного кода и, видимо, догадался уже, судя по
> 123-ий © (09.02.09 11:09) [20] > дошло уже. :)
PS Антон, у нас же тут все учителя, разумеется гениальные, так что готовых решений не надо нам :)
-
> 123-ий © (09.02.09 07:42)
Интерфейсы?
-
> Городской Шаман (09.02.09 19:23) [35]
зачем? я вчера вечером переделал в процедуру, которая в параметрах получает Strings. все норм. начиная с поста этак 8 я уже читаю чисто из спортивного интереса.
|