Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.03.2009, 13:14   #1
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию Объекты в процедурах

Привет всем!
Наверное мне должно быть стыдно за то, что я не знаю таких элементарных вещей.

Код:
procedure testProc;
var
b: tBitmap;
begin
   b := tBitmap.create;
   {здесь операции с b}
   b.free; // Это здесь обезательно?
Ведь локальные переменные уничтожаются после выполнения процедуры?
Или уничтожается только ссылка b, а сама картинка остаётся?
Altera вне форума Ответить с цитированием
Старый 04.03.2009, 14:15   #2
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

уничтожается только ссылка поэтому лучше писать
Код:
procedure testProc;
var
b: tBitmap;
begin
  b := tBitmap.create;
  try
    {здесь операции с b}
  finally
    b.free;
  end;
s.Creator вне форума Ответить с цитированием
Старый 05.03.2009, 09:03   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Или уничтожается только ссылка b, а сама картинка остаётся?
Вполне возможно. Для надежности лучше самому все уничтожать, хотя Делфи все равно потом при закрытии проги все обьекты уничтожает, но с локальными тут непонятки.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.03.2009, 21:23   #4
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Вполне возможно. Для надежности лучше самому все уничтожать, хотя Делфи все равно потом при закрытии проги все обьекты уничтожает, но с локальными тут непонятки.
У Delphi "непоняток" нет - объект не уничтожается вместе с локальной переменной которая является только ссылкой на него.
И полагаться на уничтожение при закрытии не стоит - Если локальная переменная в методе (функции) которая используется в циклах и т.д., сколько будет висячих объектов до закрытия программы ?

Если конечно разговор не идет о .NET где есть сборщик мусора и объект уничтожается после уничтожения всех ссылок на него ( но не сразу, а когда запустится этот сборщик ).

Последний раз редактировалось s.Creator; 05.03.2009 в 21:39.
s.Creator вне форума Ответить с цитированием
Старый 05.03.2009, 22:08   #5
Gorychev
Участник клуба
 
Аватар для Gorychev
 
Регистрация: 08.03.2008
Сообщений: 1,537
По умолчанию

ИМХО, наиболее правильная последовательность действий при уничтожении обьекта:
Код:
d.free;
d.nil;
после уничтожения обьекта переменная d продолжает ссылаться на местов памяти где обьекта уже нет. Если пременную предпологается повторно использовать, то лучше ей присвоить значение nil, чтобы программа могла проверить, существует обьект или нет.

Как вариант можно воспользоваться функцией FreeAndNil(d) - результат тот же.
Gorychev вне форума Ответить с цитированием
Старый 05.03.2009, 22:22   #6
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

На всякий случай напомню:
Цитата:
Free method (TObject)
Destroys an object and frees its associated memory, if necessary.
Особенно следует обратить внимание на то, что
Цитата:
For objects that are not components, or for components created with a nil owner, be sure to call Free after you are finished with them; otherwise the allocated memory will not be usable until after the application terminates.
Между прочим, ни одного слова про NIL...
mihali4 вне форума Ответить с цитированием
Старый 06.03.2009, 00:48   #7
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Простыми словами, когда Вы вызываете конструктор (create) для объекта (в том числе и для локальной переменной- это тоже объект), то Вы занимаете какую то память, где хранятся параметры этой лок. переменной.Далее при использовании ее в проге параметры передаются в какой то другой обьект.К примеру в приведенном выше примере в buffer
скачали картинку с файла , в нужный момент перевели картинку с буфера на форму .Если больше буфер не нужен - уничтожили его (Free).
Тем самым освободили память.При следующем вызове метода , где используется лок.переменная все повторится - create -> обработка -> free.
И не сомневайся даже ... отдых - кайф, работа - лажа!
DeKot вне форума Ответить с цитированием
Старый 06.03.2009, 17:23   #8
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

Немного поправлю:

Gorychev

Код:
d.free;
d := nil;
DeKot

Простыми словами цитаты Михалыча можно перевести так:

Все переменные (поля классов) объявленные как
Код:
var b: Tobject; // или его наследники
В действительности являются ссылками на объекты (хотя их ненадо разыменовывать при использовании).
Строка
Код:
p := TPanel.Create(nil);
Создает объект (т.е. выделяет для него память) и заносит в переменныю ссылку (адрес) на эту память.

Поэтому при выходе из функции (метода, процедуры) уничтожается переменная-ссылка, а выделенная память остается если к объекту не применен метод Free.
Поэтому рекомендуют использовать try ... finally для предотвращения утечки памяти

Но

у TComponent и его наследников есть механизм взаимодействия с владельцем (Owner) который позволяет сообщить владельцу при уничтожении компонента, что он им уже не владеет.
А при уничтожении владельца позволяет владельцу уничтожить всех "подчиненных" (только не путайте с Parent)

Поэтому
Код:
var Schet: Integer = 1;
procedure TForm1.Button1Click(Sender: TObject);
var p: TPanel;
begin
  p := TPanel.Create(Self); // Create(Form1)
  p.Parent := Self;
  p.Left := Random(500);
  p.Caption := 'Yes ' + IntToStr(Schet);
  Inc(Schet);
end;
при каждом нажатии на кнопку будут создаваться панели.
при выходе из метода переменная p будет уничтожаться,
но сами панели уничтожатся при уничтожении формы.
s.Creator вне форума Ответить с цитированием
Старый 06.03.2009, 17:38   #9
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Цитата:
For objects that are not components, or for components created with a nil owner, be sure to call Free after you are finished with them; otherwise the allocated memory will not be usable until after the application terminates.
Не соглашусь с переводом, тем более, что и смысл оказался несколько искажен.
Если почти дословно, то:
Цитата:
Не забывайте вызывать метод Free после окончания использования объектов, не являющихся компонентами, или компонентов, созданных с Owner=nil; в противном случае выделенная для них память будет высвобождена только после завершения приложения.
mihali4 вне форума Ответить с цитированием
Старый 07.03.2009, 13:20   #10
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Воооо понравился вам тема.... ))))

Я ещё часто встречал такие вещи:
Код:
procedure tMain_form.main_formOnClose(sender: tObjet);
begin
   freeLibrary(dllHandle);
   bitmap.free;
   ...
end;
А они разве не уничтожится после закрытия программы?
Altera вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
запутался в процедурах world12_tk Помощь студентам 6 03.03.2009 18:57
одинаковый код в процедурах jungle Помощь студентам 7 26.11.2008 22:45
MySQL - рекурсия в хранимых процедурах Банзай SQL, базы данных 0 12.08.2008 19:04
Как правильно использовать переменные в процедурах nikolai_P Microsoft Office Excel 22 15.05.2008 13:15
Материал о процедурах Jondeer Помощь студентам 18 04.12.2007 21:22