Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.023 c
14-1077797424
Иван Бездомный
2004-02-26 15:10
2004.03.28
Забавно


3-1078135473
Janbolat
2004-03-01 13:04
2004.03.28
Отображение длинных чисел в DBGride


3-1077871704
Лысый
2004-02-27 11:48
2004.03.28
Добавить запись


1-1078652605
Max
2004-03-07 12:43
2004.03.28
Заполнение и очистка TList


3-1076950170
freshman
2004-02-16 19:49
2004.03.28
Как сделать цикл чтения БД




   Наверх