![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему освобождённые объекты не ссылаются на nil [D7, WinXP]
alex_ant © (2007-10-21 17:50:00)Внутри объекта используются ещё 3 однотипных объекта, реализация которых была реализована не мной (она закрыта от меня). В деструкторе своего объекта я освобождаю их:
destructor TMyObj.Destroy();
begin
OtherObj1.Free();
OtherObj3.Free();
OtherObj3.Free();
end;
После вызова Free(), внутри деструктора, эти объекты начинают ссылаться на nil, и всё вроде бы логично. Но извне, некоторые объекты оказываются неравны nil.
MyObj.Destroy(); //Внутри после освобождения все в nil
//Тут эти подобъекты уже не равны nil
if (MyObj.OtherObj1 = nil) and (MyObj.OtherObj2 = nil) and (MyObj.OtherObj3 = nil) then
ShowMessage('Объекты ссылаются на nil')
else
ShowMessage('Объекты НЕ ссылаются на nil');
У меня всегда выводит «Объекты НЕ освободились». Причём средний объект равен nil, но другие ссылаются куда-то.
Сразу говорю, что вызываю MyObj.Destroy() вместо рекомендованного MyObj.Free(), чтобы проверить правильность освобождения подобъектов (этот вызов производится в тестах).
Так вот вопрос: нормальное ли это поведение что после освобождения дочерних объектов в деструкторе, во внешнем представлении они оказываются неравны nil? Подозреваю, что где-то косяк, но где искать не пойму — в деструкторе всё в nil, и как только выхожу из него, освобождённые объекты перестают ссылаться на nil. Как исправить такое непонятно. Пишу вычислительное приложение и потому, всякие там утечки памяти крайне нежелательны.
Заранее благодарю за советы.
P. S. Дочерние объекты, реализованные не мной, предоставляет платный пакет одной крутой фирмы, так что ошибки в них крайне маловероятны.
alex_ant (2007-10-22 21:17:00) [1]
> Сергей М. © (22.10.07 17:15) [30]
> Нафига человеку со зрением 1.0 на оба глаза носить очки
> с диоптриями ?)
Это философский вопрос. Все у кого железная внимательность, давно строчат гуёвые приложения в машинных кодах. :) Люди попроще пишут в Delphi, ещё и тестами модулей...
Сергей М. (2007-10-22 17:15:00) [2]
> есть ещё тесты модулей для обострения внимательности
Нафига человеку со зрением 1.0 на оба глаза носить очки с диоптриями ?)
alex_ant (2007-10-22 17:10:00) [3]
> Сергей М. © (22.10.07 12:52) [21]
> Будь внимательней и освобождай все 3.
Да я внимательный, просто есть ещё тесты модулей для обострения внимательности. Их использование для этой задачи и хотел изучить.
Anatoly Podgoretsky (2007-10-22 16:35:00) [4]> Slym (22.10.2007 12:53:22) [22]
Что позволено Юпитеру, не позволено быку, кроме того у них Дельфи нет.
Anatoly Podgoretsky (2007-10-22 16:34:00) [5]> alex_ant (22.10.2007 12:47:20) [20]
Никогда так не делай, это не программа, а ужас.
vpbar (2007-10-22 13:23:00) [6]Ага. Еще вариант перейти в net, где все ссылаки на счету. Или в делфи с объектами работать через интерфейсы
Ins (2007-10-22 12:56:00) [7]
> А если лениво освобождать "ручками", сделай все свои объекты
> наследниками TComponent, тогда все упрощается (см. справку
> "Owner property (TComponent)")
Да много вариантов, на самом деле... заносить в TObjectList, наследовать от TComponent или TInterfacedObject... Выбирай на вкус.
alex_ant (2007-10-22 12:53:00) [8]В общем, спасибо всем за помощь. Insна путь истинный направил. :)
homm (2007-10-22 12:53:00) [9]> [20] alex_ant (22.10.07 12:47)
> А если я сделал 3 подобъекта, и по невнимательности освободил
> только 2. Память будет засорена. Могу ли я проверить как-
> то программно, что я забыл освободить третий подобъект?
Можешь программно, но лучше аппаратно, освободить там, где забыл.
Slym (2007-10-22 12:53:00) [10]alex_ant (22.10.07 12:47) [20]
по невнимательности
Микрасофт тоже в основном по "невнимательности", а потом патчи делает и ничего :)
Память будет засорена
Я бы сказал потеряна, и не всегда только память: у системы многа разных ресурсов (хендлы, GDI и пр.)
Сергей М. (2007-10-22 12:52:00) [11]
> если я сделал 3 подобъекта, и по невнимательности освободил
> только 2
Будь внимательней и освобождай все 3.
А если лениво освобождать "ручками", сделай все свои объекты наследниками TComponent, тогда все упрощается (см. справку "Owner property (TComponent)")
alex_ant (2007-10-22 12:47:00) [12]
> Ins © (22.10.07 12:39) [19]
> Вы случайно не Алексей Федоров? :)
Он самый. Не только я, значит, на два фронта работаю. :)))
> Сергей М. © (22.10.07 12:27) [18]
> Если ты вызвал метод Free некоего объекта и при этом не
> схлопотал исключение, можешь практически со 100%-ной уверенностью
> считать, что этот объект тобой уничтожен.
А если я сделал 3 подобъекта, и по невнимательности освободил только 2. Память будет засорена. Могу ли я проверить как-то программно, что я забыл освободить третий подобъект?
Ins (2007-10-22 12:39:00) [13]
> alex_ant © (21.10.07 17:50)
Вы случайно не Алексей Федоров? :)
Сергей М. (2007-10-22 12:27:00) [14]
> вопрос можно ли проверить правильность деструктора (что
> все подобъекты освободились полностью) остался так и неясен
Если ты вызвал метод Free некоего объекта и при этом не схлопотал исключение, можешь практически со 100%-ной уверенностью считать, что этот объект тобой уничтожен.
Ins (2007-10-22 12:21:00) [15]
> Ведь объекты живут вне зависимости от того, есть ли на них
> ссылка, и если родительский объект умер, дочерний может
> ещё засорять память..
Нужно просто при уничтожении т.н. родительского объекта, уничтожать дочерний. И не нужно ни за чем следить. Если сами для него (дочернего) Free в деструкторе родительского вызовите - расслабьтесь и получайте удовольствие.
alex_ant (2007-10-22 12:15:00) [16]
> Юрий Зотов © (22.10.07 00:22) [12]
> Жил человек. Его адрес (или телефон) был записан у N других
> людей. Причем он даже и сам не знает, у кого именно. И даже
> чему равно N - он тоже не знает. И никто этого не знает.
Спасибо очень понятное такое сравнение. :)
Нашел вот интересную статью по теме:
http://softwarer.ru/memory.html
Понятно теперь, что переменная освобождённого объекта не обязательно ссылается на nil, но вопрос можно ли проверить правильность деструктора (что все подобъекты освободились полностью) остался так и неясен...
Ведь объекты живут вне зависимости от того, есть ли на них ссылка, и если родительский объект умер, дочерний может ещё засорять память... В общем-то затею с nil, я начал именно, чтобы научиться проверять освобождение подобъектов... а как это сделать, теперь тем более не ясно.
Германн (2007-10-22 04:27:00) [17]
> даже рука не поднимается назвать это «оффтопом».
>
А с чего бы именно рука поднялась бы? :-)
Уж сколько раз твердили миру, но всё равно. The gods themselves contains in vain :)
Джо (2007-10-22 03:16:00) [18]> [13] Германн © (22.10.07 00:46)
> Нет повести печальнее на свете, чем повесть о разрушенном
> объекте :(
Хао! даже рука не поднимается назвать это «оффтопом».
Германн (2007-10-22 00:46:00) [19]Нет повести печальнее на свете, чем повесть о разрушенном объекте :(
Юрий Зотов (2007-10-22 00:22:00) [20]> alex_ant © (21.10.07 17:50)
> Почему освобождённые объекты не ссылаются на nil [D7, WinXP]
Жил человек. Его адрес (или телефон) был записан у N других людей. Причем он даже и сам не знает, у кого именно. И даже чему равно N - он тоже не знает. И никто этого не знает.
Человек умер. А что стало с этими самыми N записями?
Они исчезли? Нет. Ведь их никто не уничтожал.
Они изменились? Нет. Ведь их никто не менял.
Они остались точно такими же, какими и были. Но стали неправильными. Потому что этот человек по этому адресу более не живет.
Аналогию чувствуете? В программе было N ссылок на один и тот же объект. Сам объект об этих ссылках, естественно, ничего не знает. И даже не знает, есть ли они вообще и сколько их.
Программист разрушает объект. Вопрос - каким волшебным образом объект может обнулить ссылки на себя, если об этих ссылках ему абсолютно ничего не известно?
Эти ссылки остались точно такими же, какими и были. Но стали неправильными. Потому что этот объект по этому адресу более не живет.