Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему освобождённые объекты не ссылаются на nil [D7, WinXP]


Страницы:   1 2

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. Дочерние объекты, реализованные не мной, предоставляет платный пакет одной крутой фирмы, так что ошибки в них крайне маловероятны.


vpbar   (2007-10-21 22:42:00) [21]

>> Так вот вопрос: нормальное ли это поведение
Да, нормальное. Free вызывает деструктор и разрушает объект. Но переменную, естественно, в nil ты должен сам установить. (c) [1]

>>Да, но они уже установленны в nil внутри деструктора. Я проверял.
В каком деструкторе?
Если в этом
destructor TMyObj.Destroy();
begin
OtherObj1.Free();
OtherObj2.Free();
OtherObj3.Free();
OtherObj1 := nil;
OtherObj2 := nil;
OtherObj3 := nil;
end;

То переменные OtherObj1 ... OtherObj3 должны быть равны nil, если только после этого им ничего не присваивать.

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


alex_ant   (2007-10-21 22:14:00) [22]


> Плохиш ©   (21.10.07 21:19) [9]
> Потому что "мусор" может быть nil, а может и не быть...

А... круто! :) Резонное замечание, что-то раньше я не додумался... :)))


Плохиш   (2007-10-21 21:19:00) [23]


> Почему некторые MyObj.OtherObj равны nil, а некоторые не
> равны?

Потому что "мусор" может быть nil, а может и не быть...


Leonid Troyanovsky   (2007-10-21 20:40:00) [24]


> alex_ant ©   (21.10.07 20:04) [7]

> Ну допустим, а вывод какой? Почему некторые MyObj.OtherObj
> равны nil, а некоторые не равны?

Допустим что MyObj = MyObj1 = .. = MyObjN.
Присвоим MyObj := nil,
чему будет равен MyObjX.

--
Regards, LVT.


alex_ant   (2007-10-21 20:04:00) [25]


> Jump   (21.10.07 18:17) [3]
> Давай, поставь двоечку...

Да это я в примере ошибся, на самом деле имена у всех осмысленные и ошибка точно не в этом.


> Однокамушкин   (21.10.07 19:05) [4]
> Очень грубая ошибка - сначала делаете MyObj.Destroy, а потом
> обращаетесь к MyObj... Правило, которому нужно следовать
> неукоснительно: вызвали Destroy (или Free) - всё, забыли
> про такой объект, никаких обращений к нему

А как узнать, что память освободилась корректно? Я в общем-то так всегда и поступал, а тут решил проверить производится ли правильное освобождение...


> Leonid Troyanovsky ©   (21.10.07 19:18) [5]
> MyObj.OtherObj1 <> OtherObj1

Ну допустим, а вывод какой? Почему некторые MyObj.OtherObj равны nil, а некоторые не равны?


Leonid Troyanovsky   (2007-10-21 19:19:00) [26]


> Jump   (21.10.07 18:17) [3]

> Давай, поставь двоечку...

Легко.

--
Regards, LVT.


Leonid Troyanovsky   (2007-10-21 19:18:00) [27]


> alex_ant ©   (21.10.07 18:13) [2]

> Кроме того, это первое что я испробовал: после освобождения
> сам установил всё в nil

MyObj.OtherObj1 <> OtherObj1

--
Regards, LVT.


Однокамушкин   (2007-10-21 19:05:00) [28]


> MyObj.Destroy(); //Внутри после освобождения все в nil
> //Тут эти подобъекты уже не равны nil
> if (MyObj.OtherObj1 = nil) and (MyObj.OtherObj2 = nil) and
> (MyObj.OtherObj3 = nil) then

Очень грубая ошибка - сначала делаете MyObj.Destroy, а потом обращаетесь к MyObj... Правило, которому нужно следовать неукоснительно: вызвали Destroy (или Free) - всё, забыли про такой объект, никаких обращений к нему


Jump   (2007-10-21 18:17:00) [29]

OtherObj1.Free();
OtherObj 3.Free();
OtherObj3.Free();
OtherObj1 := nil;
OtherObj 3:= nil;
OtherObj3 := nil;


Давай, поставь двоечку...


alex_ant   (2007-10-21 18:13:00) [30]


> Да, нормальное. Free вызывает деструктор и разрушает объект.
>  Но переменную, естественно, в nil ты должен сам установить.


Да, но они уже установленны в nil внутри деструктора. Я проверял.

Кроме того, это первое что я испробовал: после освобождения сам установил всё в nil:

destructor TMyObj.Destroy();
begin
 OtherObj1.Free();
 OtherObj3.Free();
 OtherObj3.Free();
 OtherObj1 := nil;
 OtherObj3 := nil;
 OtherObj3 := nil;
end;

Но... ситуация не изменилась. Описываемый мной глюк остался. Как такое может быть???


DrPass   (2007-10-21 17:57:00) [31]


> Так вот вопрос: нормальное ли это поведение

Да, нормальное. Free вызывает деструктор и разрушает объект. Но переменную, естественно, в nil ты должен сам установить.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо