Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1233903923
Кое кто
2009-02-06 10:05
2009.04.12
Реально ли перейти на бумажные пакеты?


2-1235124425
markers
2009-02-20 13:07
2009.04.12
Свой трей


15-1234474201
Юрий
2009-02-13 00:30
2009.04.12
С днем рождения ! 13 февраля 2009 пятница


2-1235327758
mm_ash
2009-02-22 21:35
2009.04.12
Dataset Buffers


2-1235045880
charoey_mag
2009-02-19 15:18
2009.04.12
Права доступа





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский