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

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

Не уничтожается объект [D7, XP]


Константин ©   (2010-03-22 15:47:00) 

Допустим у нас есть у объекта Object1 поле типа TObject2 и ObjеctList с объектами TObject2 который ими владеет.
В креате Object1  полю Object2 присваивается nil.
В какой то момент я присваиваю этому полю ссылку на объект из ObjеctList
Object1.Object2 := ObjеctList[i];
и потом в какой то момент делаю ObjеctList.Delete[i], но судя по дебаггеру в поле Object1.Object2 этот объект присутствует и Object2 не равен nil. Почему так происходит?


Дмитрий Белькевич   (2010-03-23 11:14:00) [1]


> Можно сравнивать известную ссылку на объект, который хотим
> удалить, со всеми остальными - если две ссылки равны - значит
> они ссылаются на один и тот же объект (если тип один и тот
> же)


Тип - пофиг. Если адреса ссылок равны - то и ссылки равны.


> Может есть какой-то другой? как то через интерфейс или типа
> того?


Задачу расскажи, чего нужно. Пока что какие-то туманные телодвижения с объектами.


> Обо ВСЕХ ссылках на объект в своей программе знает только
> ПРОГРАММИСТ. Поэтому только он один может (и должен!) написать
> код, который все эти ссылки очистит (то есть, присвоит им
> nil).


А по хорошему, хранить только одну ссылку. Так обычно надёжнее и меньше возни с очисткой дохлых ссылок.


Константин   (2010-03-22 20:22:00) [2]

ну я так понимаю мне надо хранить ссылки на объекты, которые ссылаются на удаляемый (в нём хранить) и деструкторе им присваивать nil
Думаю это будет нормальный способ.
Может есть какой-то другой? как то через интерфейс или типа того?


Anatoly Podgoretsky   (2010-03-22 19:24:00) [3]

> К  (22.03.2010 16:43:04)  [4]

Ты что сканируешь память на физическом уровне?


Anatoly Podgoretsky   (2010-03-22 19:24:00) [4]

> Константин  (22.03.2010 18:03:09)  [9]

А В, а С забыл, а в других модуляхне?


И. Павел   (2010-03-22 18:25:00) [5]


> тобишь надо? правильно?

ИМХО не совсем. В приведенном мною примере работать будет. Но вы же можете создать несколько объектов TB: B1, B2, B3. И соответствующие им: A1, A2, A3.

Как пример:
Все ссылки могут храниться в одном ObjectList. Можно сравнивать известную ссылку на объект, который хотим удалить, со всеми остальными - если две ссылки равны - значит они ссылаются на один и тот же объект (если тип один и тот же). Удаляем объект, а всем этим ссылкам присваиваем nil.


Медвежонок Пятачок   (2010-03-22 18:08:00) [6]

А при чем здесь лист и его смещения, если ссылка осталась и сидит в Object1.Object2 ?


Константин   (2010-03-22 18:03:00) [7]


> И. Павел ©   (22.03.10 16:52) [5]

тобишь надо? правильно?
destructor TB.Destroy; override;
begin
A := nil;
end;


> Инопланетянин   (22.03.10 17:38) [7]

То есть когда обджек лист освобождает объект он не смещает указатели?


oldman   (2010-03-22 17:49:00) [8]


> Почему так происходит?


то есть, рисовать на бумажке блок-схему алгоритма и думать нам лень?


Инопланетянин   (2010-03-22 17:38:00) [9]

> К   (22.03.10 16:43) [4]

Я создал объект и завел на него сто ссылок. Или тыщу. Или миллион. Знает ли объект об этих ссылках?

Нет, сам по себе не знает. И никакой другой объект в моей программе об этих ссылках тоже сам по себе не знает. Даже TObjectList, если я включу в него этот объект, знает только об одной (своей внутренней) ссылке, а про остальные 999999 ему ничего неизвестно.

Теперь я уничтожил этот объект. Может ли он в своем деструкторе сам  очистить все ссылки на себя?

Нет, не может - ведь он ни о каких ссылках ничего не знает.

Тогда я стал уничтожать объект не напрямую, а чарез TObjectList. Догадываетесь, что происходит?

Правильно - одна ссылка (внутренняя в TObjectList) исчезает из списка, а с остальными ссылками НЕ ПРОИСХОДИТ НИЧЕГО. Они как были, так и остались. Да и с чего бы им меняться, если их никто не менял?

Обо ВСЕХ ссылках на объект в своей программе знает только ПРОГРАММИСТ. Поэтому только он один может (и должен!) написать код, который все эти ссылки очистит (то есть, присвоит им nil).


И. Павел   (2010-03-22 16:52:00) [10]

A:=TA.Create;
A:=B;
B.Free;

После этого и A и B все еще будут ссылаться на участок памяти, где раньше был объект. B.Free - это не очищение B, это удаление объекта, на который ссыллается B. Для того, чтобы очистить B нужно написать B:=nil.


И. Павел   (2010-03-22 16:52:00) [11]

A:=B; -> B:=A;


К   (2010-03-22 16:43:00) [12]


> Anatoly Podgoretsky ©   (22.03.10 15:54) [3]

не, я делаю overload у TList.Delete где нахожу все ссылки и ставлю им nil ;)

Я просто не особо пойму что такое nil. Тобишь когда TObjectList  сделал Free, объект освободил память, а указатель остался? Вернее получается что в TObjectList происходит сдвиг и фактически этот указатель указывает на уже другой объект, если в TObjectList было больше двух объектов?


Anatoly Podgoretsky   (2010-03-22 15:54:00) [13]


> Когда уничтожаете объект - устанавливайте все ссылки на
> него в nil.

Для этого заводи еще несколько ObjеctList :-)


И. Павел   (2010-03-22 15:53:00) [14]

Кажется это уже обсуждалось пару дней назад.
Object1.Object2 ничего не знает об удаление объекта. Он продолжает хранить адрес. Когда уничтожаете объект - устанавливайте все ссылки на него в nil.


Anatoly Podgoretsky   (2010-03-22 15:53:00) [15]

> Константин  (22.03.2010 15:47:00)  [0]

А ты что нибудь сделал для этого?


Наверх

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