Форум: "Прочее";
Текущий архив: 2009.04.12;
Скачать: [xml.tar.bz2];
Вниз
Вопрос по уничтожению объектов Найти похожие ветки
← →
123-ий © (2009-02-09 07:42) [0]Тут как бы надо знать устройство дельфового менеджера памяти на более высоком уровне, чем его знаю я. Поэтому спрошу в сюда.
вот код:
function GetSomeList: TStringList;
begin
Result := TStringList.Create;
// Заполняю стринглист
end;
далее я вызываю данную функцию, например
SomeListBox.Items := GetSomeList;
теперь результат работы функции GetSomeList надо как-то уничтожить.
Если сделатьGetSomeList.Free
- функция выполняется два раза, а это не оптимально, да и порой неудобно. Каким образом лучше реализовать? То есть мне просто надо сделать функцию, возвращающую стринглист и чтобы без утечки памяти.
← →
MBo © (2009-02-09 07:50) [1]сделай процедуру, которой передаешь созданный TStringList, потом его уничтожаешь, когда нужно.
← →
Palladin © (2009-02-09 08:04) [2]
Procedure FillStringList(p_theSL:TStringList);
Begin
.. заполняем
End;
Var
theSL:TStringList;
Begin
theSL:=TStringList;
Try
FillStringList(theSL);
...
Finally
theSL.Free;
End;
End;
это - правильно
← →
Palladin © (2009-02-09 08:06) [3]зачем создавать TStringList для св-ва TStrings если оно уже создано и используется в объекте
Procedure FillStringList(p_theSL:TStrings);
Begin
.. заполняем
End;
FillStringList(SomeListBox.Items);
← →
korneley © (2009-02-09 08:13) [4]
> Palladin © (09.02.09 08:04) [2]
> theSL:=TStringList;theSL:=TStringList.Create;
Я не смеюсь, мало ли, чего недопонял :)
← →
Palladin © (2009-02-09 08:13) [5]:) никто не застрахован от описек и недописек :)
← →
Skyle © (2009-02-09 08:22) [6]
> korneley © (09.02.09 08:13) [4]
Это не чистый дельфи, это Palladin Delphi Extension ®
← →
123-ий © (2009-02-09 09:27) [7]
> 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 этот самый стринглист должен умереть. Я прав?
← →
Сергей М. © (2009-02-09 09:30) [8]
> 123-ий © (09.02.09 09:27) [7]
> Я прав?
Угу.
← →
Palladin © (2009-02-09 09:41) [9]
> 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; // бесполезно, объект создан, но исключение произошло не в Try/Finally, а во время выполнения функции, соответственно после исключения при назначении свойству значения, ссылка на созданный объект теряется
End;
End;
← →
KSergey © (2009-02-09 09:42) [10]> Palladin © (09.02.09 08:04) [2]
> Procedure FillStringList(p_theSL:TStringList);
> Begin
> .. заполняем
> End;
Тогда даже лучшеProcedure FillStringList(p_theSL:TStrings);
Тогда туда можно будет передавать в том числе и Items от SomeListBox и не придется создавать временный, а потом из него копировать.
← →
Palladin © (2009-02-09 09:43) [11]Именно в [3], по этому поводу, я и исправился, более внимательней прочитав вопрос )
← →
KSergey © (2009-02-09 09:44) [12]> Palladin © (09.02.09 09:43) [11]
а, точно, не заметил, сорри.
← →
KSergey © (2009-02-09 09:45) [13]А почему вопрос задан в потрепаться, а не в тематической?? вполне себе тематический вопрос, по-моему.
← →
Anatoly Podgoretsky © (2009-02-09 09:51) [14]> Palladin (09.02.2009 9:41:09) [9]
Это можно легко исправить, немного переделав функцию, но смысла нет.
← →
123-ий © (2009-02-09 10:03) [15]
> KSergey © (09.02.09 09:45) [13]
на всякий случай. туда предпочитаю не лазить почему то. :)
> Anatoly Podgoretsky © (09.02.09 09:51) [14]
смысла то нет, а все тки расскажите. =) интересно
← →
test © (2009-02-09 10:15) [16]KSergey © (09.02.09 09:45) [13]
Тут мастеров больше ))
← →
KSergey © (2009-02-09 10:24) [17]> 123-ий © (09.02.09 10:03) [15]
> смысла то нет, а все тки расскажите. =) интересно
А самому подумать? как подсказка - try/except
← →
Rouse_ © (2009-02-09 10:41) [18]А я вот немного не пойму, пример в [0] был тестовый или взятый из "реальной жизни"? Просто зачем создавать промежуточный TStringList если он уже создан в SomeListBox? Может проще брать его оттуда и использовать? Зачем лишние затраты на создание класса и вызов Assign-а при присвоении?
← →
{RASkov} © (2009-02-09 10:59) [19]> [0] 123-ий © (09.02.09 07:42)
> GetSomeList.Free - функция выполняется два раза, а это не оптимально, да и порой неудобно.
Более того.... Неправильно, ибо память, выделенная в первом вызове, так и утекет в никуда....
← →
123-ий © (2009-02-09 11:09) [20]
> KSergey © (09.02.09 10:24) [17]
дошло уже. :)
> Rouse_ © (09.02.09 10:41) [18]
ну как сказать, просто есть один листбокс и несколько функций, которые должны его заполнять ибо разные функции заполняют его разными данными. собственно они заполняют даже не какойто один определенный заранее листбокс, а несколько. короче тут как раз катит вариант предложенный палладином.
> {RASkov} © (09.02.09 10:59) [19]
вот вот, оно и выглядело как то странно. действительно, если бы я сразу подумал, ведь вызвав эту функцию два раза, я два раза создам СтрингЛист, а уничтожится он только во второй раз.
← →
Anatoly Podgoretsky © (2009-02-09 11:23) [21]> 123-ий (09.02.2009 10:03:15) [15]
Ввести кроме создания еще и обработку ошибок там же, при ошибке разрушать, если был создан и игнорировать разрушение в процем случае, наружу выдавать nil и возможно исключение.
← →
Anatoly Podgoretsky © (2009-02-09 11:24) [22]> 123-ий (09.02.2009 11:09:20) [20]
Это глупо, если вызван два раза, то и разрушать должен два раза, каждый экземпляр.
← →
Palladin © (2009-02-09 12:48) [23]
> Anatoly Podgoretsky © (09.02.09 11:23) [21]
Угу, разрушать в функции создающей, это как гланды вырезать через другой проход.
Создание - конструктору, инициализация - в безопасном месте.
← →
Rouse_ © (2009-02-09 12:55) [24]
> ну как сказать, просто есть один листбокс и несколько функций,
> которые должны его заполнять ибо разные функции заполняют
> его разными данными
Ну так делай у каждой функции констатарный параметр в который приходит TStrings и пусть они этот TStrings и заполняют, какая разница что это будет, Items или руками созданный TStringList
← →
Rouse_ © (2009-02-09 13:21) [25]Хм... немножко разьясню [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);
Вот как-то так...
← →
KSergey © (2009-02-09 13:25) [26]> Rouse_ © (09.02.09 13:21) [25]
> Хм... немножко разьясню [24], а то начали в аське переспрашивать :)
Это те, кто не смог прочитать [3] и [10]?! Нахрен на них время-то тратить??
← →
Palladin © (2009-02-09 13:29) [27]:)))) и то правда
← →
123-ий © (2009-02-09 13:29) [28]
> Rouse_ © (09.02.09 12:55) [24]
дык я ж написал что так и сделаю в
> 123-ий © (09.02.09 09:27) [7]
, первая строчка =))
← →
Rouse_ © (2009-02-09 13:30) [29]
> Это те, кто не смог прочитать [3] и [10]?! Нахрен на них
> время-то тратить??
Видимо не внимательно прочитал :)))) Пардоньте :)
← →
123-ий © (2009-02-09 14:07) [30]
> Видимо не внимательно прочитал :)))) Пардоньте :)
бывает =)))
← →
Anatoly Podgoretsky © (2009-02-09 14:38) [31]> Palladin (09.02.2009 12:48:23) [23]
Ты вне темы - речь идет об разрушение в случае ошибки.
← →
Григорьев Антон © (2009-02-09 16:28) [32]
> 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;
← →
Palladin © (2009-02-09 16:38) [33]
> Григорьев Антон © (09.02.09 16:28) [32]
В лишних телодвижениях, зачем нужно отслеживать в отдельном блоке try/except успешность назначения свойств, если гораздо логичней и понятней штатный вызов конструктора и уже далее в try/finally ассигнование свойств. Для себя же пишем. Не смущайте начинающих.
← →
KSergey © (2009-02-09 17:53) [34]> Григорьев Антон © (09.02.09 16:28) [32]
> И в чём проблема?
Проблемы нет, лишь обратили на это внимание автора, предполагалось, что до этого он и сам догадается до приведенного кода и, видимо, догадался уже, судя по
> 123-ий © (09.02.09 11:09) [20]
> дошло уже. :)
PS
Антон, у нас же тут все учителя, разумеется гениальные, так что готовых решений не надо нам :)
← →
Городской Шаман (2009-02-09 19:23) [35]
> 123-ий © (09.02.09 07:42)
Интерфейсы?
← →
123-ий © (2009-02-10 06:31) [36]
> Городской Шаман (09.02.09 19:23) [35]
зачем? я вчера вечером переделал в процедуру, которая в параметрах получает Strings. все норм. начиная с поста этак 8 я уже читаю чисто из спортивного интереса.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2009.04.12;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.005 c