![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не уничтожается объект [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]
А ты что нибудь сделал для этого?