Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.12;
Скачать: CL | DM;

Вниз

Вопрос по уничтожению объектов   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.014 c
2-1235467319
В-В
2009-02-24 12:21
2009.04.12
Нужно запустить сетевое подключение с программы


2-1235489040
cosinus
2009-02-24 18:24
2009.04.12
Как получить handle контрола в чужом приложении?


2-1235554500
Scot Storch
2009-02-25 12:35
2009.04.12
Сохранить результа запроса в список


15-1233676974
Снеговик-2009
2009-02-03 19:02
2009.04.12
ICQ сдохла! :-))) Я преждал про джаббер...


15-1234440948
Michael
2009-02-12 15:15
2009.04.12
Алгоритм декодирования JPEG