Текущий архив: 2004.03.28;
Скачать: CL | DM;
Вниз
Утечки памяти Найти похожие ветки
← →
Андрей Пономарев (2004-03-02 12:48) [0]Уважаемые мастера!
Пусть есть некоторый класс TClassA, в котором есть
свойство:
property SomeProp : TClassA read FGetSomeProp;
При выполнении метода FGetSomeProp создается новый экземпляр
класса TClassA.
Вопросы:
1) Будет ли утечка памяти при обращении вида:
SomeVar := ClassA.SomeProp.SomeProp. ... .SomeOtherProp;
(при выполнении этой цепочки экземпляры создаются, но
явно нигде не убиваются)
2) Если утечка будет, то как можно ее избежать?
Заранее спасибо.
С уважением,
Андрей Пономарев
← →
Reindeer Moss Eater © (2004-03-02 12:50) [1]1.Утечка будет
2.Не делать так
← →
Тимохов © (2004-03-02 12:53) [2]Согласен с 1.
Можно еще запоминать, объекты которые создал и в деструкторе класса TClassA их убивать.
← →
Reindeer Moss Eater © (2004-03-02 12:55) [3]Впрочем если этот класс - наследник TComponent и у всех экземпляров есть Owner, которого убивают, то утечки не будет.
← →
Пономарев Андрей (2004-03-02 12:59) [4]Что ж, будем думать - всем спасибо...
...а убивать в деструкторе TClassA их нельзя, потому что может быть такое:
SomeObj := ClassA.SomeProp.SomeProp;
SomeObj.Free;
И приехали. :)
← →
Тимохов © (2004-03-02 12:59) [5]Можешь пользоваться интерфейсами - там все само будет убиваться.
← →
Reindeer Moss Eater © (2004-03-02 12:59) [6]Но все равно, не кури больше так много.
Допустим я пользователь этого класса.
Мне в трех местах программы нужно знать свойство компонента.
Допустим я экономлю на буферных переменных и три раза читаю само свойство.
А если 10 раз?
← →
Пономарев Андрей (2004-03-02 13:06) [7]Reindeer Moss Eater:
Не понял, в чем подвох?
Вообще-то я пытаюсь написать объектную оболочку для настольных таблиц, и подобные вещи рождаются вполне закономерно при наличии самоссылающихся отношений. В любой ОО СУБД интерфейс у них будет содержать такое вот загадочное SomeProp.
← →
Тимохов © (2004-03-02 13:08) [8]
>
> Пономарев Андрей (02.03.04 13:06) [7]
Подумай про интерфейсы. Там подсчет ссылок на себя возьмет дельфи. Никто объект не использует - удаляет. Использует - тогда не удаляет.
← →
Пономарев Андрей (2004-03-02 13:08) [9]...а в примере с "приехали" было, конечно,
...
ClassA.Free;
← →
Пономарев Андрей (2004-03-02 13:10) [10]Да-да-да, насчет интерфейсов - это дельная мысль, так, скорее всего, и сделаю! Спасибо!
← →
Пономарев Андрей (2004-03-04 22:59) [11]Что-то я подумал насчет это "дельной мысли"... и понял, что ничего не понял. Во-первых, насколько я знаю, подсчет ссылок работает не столько для интерфейсов, сколько для компонентов (я встречался только с подобными COM-компонентами). Во-вторых, остается непонятным, даже если я унаследую свой класс от TInterfacedObject и буду создавать его как
var
foo : ISomeInt;
...
foo := TClassA.Create;
кто будет говорить AddRef и Release? Или я не должен создавать так, а должен обращаться к какому-нибудь "инстанциатору"?
Поясните, пожалуйста!
...а BoundsChecker безмолвствует...
← →
icWasya © (2004-03-05 09:46) [12]to [11]
вот когда сделаешь так
var // 1
foo : ISomeInt; // 2
begin // 3
...
foo := TClassA.Create; // 4
...
end; // 5
и пройдешся отладчиком, то увидишь, что за строкой 4 стоит примерно такой код
foo.Release;
@temp := TClassA.Create;
@temp.queryinterface(ISomeInt,foo);
foo.Addref;
а за строкой 5
foo.Release;
← →
Anatoly Podgoretsky © (2004-03-05 10:24) [13]Утечки и здесь нет, цепочка как существовала как единое целое так и существует. Утечка появится тогда когда ты удалишь голову и не ужадишь хвост, тогда цепочка повиснет в памяти до завершения программы.
Надо в деструкторе Destroy добавить только одну строку - SomeProp.Free, это работать будет рекурсивно.
← →
Синее безмозглое © (2004-03-05 10:42) [14]to [13]
Мне кажется, что если добавить в Destroy SomeProp.Free, то исполнение такого кода
SomeObj := ClassA.SomeProp.SomeProp.SomeProp;
ClassA.Free;
приведет к "нечаянному" убийству SomeObj. Разве нет?
← →
Синее безмозглое © (2004-03-05 10:49) [15]И вообще... в [1] сказано, что такого поля в классе нет, объект создается методом и отдается тому, кто этот метод вызвал.
← →
vl_chel © (2004-03-05 13:52) [16]TClassA = class(TInterfacedObject,ISomeInt)
если наследуешь от TObject _AddRef и _Release придется писать руками
Страницы: 1 вся ветка
Текущий архив: 2004.03.28;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.024 c