Re[10]: освобождение памяти при работе с динамическими объек
От: Leonid Troyanovsky  
Дата: 12.09.03 09:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нет декструкторы я все перекрывал, все как положено.

А>просто делалось так освободил свое вызови парент destroy.

Чего-то я не уяснил, как и что тебе удалось

А>[pascal]

А>destructor TDBQuery.Destroy;
А>var I:Integer;
А>HS:THeapStatus;
А>begin
А>if Assigned(FSelectClause) then
А> FSelectClause.Free;
А>if Assigned(FWhereClause) then
А> FWhereClause.Free;
А> inherited destroy;
А>end;

Ты, уж если приводишь части кода, то привел бы минимально
достаточный для понимания (компиляции) пример, который
любой любознательный человек мог бы воспроизвести у себя.
Глядишь, обсуждение стало бы более плодотворным


А>destructor TDBSelectClause.Destroy;

А>begin
А>if Assigned(fTableList) then
А> fTableList.Free;
А> inherited Destroy;
А>end;

Ну ты же видел реализацию Free — там уже есть if Assigned(..),
т.е. просто fTableList.Free;


А>а inherited Destroy в TDBQuery TObject.destroy

А>ну а в списках конечный вариант так же TObject.destroy
А>т.е. я о чем говорю — что придется самому управлять созданием
А>ну это хоть разбивает ту иллюзию что Delphi сам все рулит.

Так в чем у тебя сомнения? Что List{as TList}.Free не освобождает память?
IMHO, по крайней мере, с ним все нормально.
Другое дело, если ты например, заполнил его ссылками на объекты — то они будут жить до своего Free.
Примерно тоже можно сказать про объектные ссылки в полях твоего объекта (если они, например, бесхозные компоненты)

--
С уважением, LVT.
--
С уважением, LVT
Re[11]: освобождение памяти при работе с динамическими объек
От: vedmalex Россия  
Дата: 13.09.03 04:41
Оценка:
Ок, Привожу часть кода.
объект Объект Lists — Реулизует двунаправленный список
type
  TElement = class (TObject)
  public
    Next: TElement;
    Prev: TElement;
    constructor Create;
    function Copy: TElement; virtual;
    function ViewState:string;virtual;
    destructor Destroy; override;
  end;
  
  TLists = class (TElement)
  protected
    FCount: Word;
    FCurrent: TElement;
    Head: TElement;
    Tail: TElement;
    function GetEmpty: Boolean;
  public
    function Consist:Boolean;
    constructor Create;
    destructor Destroy; override;
    procedure AppendToBottom(R: TElement);
    procedure AppendToTop(R: TElement);
    function Back(var R): Boolean;
    procedure Exclude(R : TElement);
    function ExtractFromTop: TElement;
    function ExtractFromBottom:TElement;
    function FForward(var R): Boolean;
    function ReWind(var R): Boolean;
    function Skip(var R): Boolean;
    property Count: Word read FCount;
    property Current: TElement read FCurrent;
    property Empty: Boolean read GetEmpty;
  end;


Деструктор выфглядит следующим образом:
destructor TLists.Destroy;
var
  R: TElement;
begin
if FCount > 0 then
  while Assigned(Tail) do
   begin
    R:=Tail.Next;
    Tail.Free;
    Tail:=R;
   end;
  FCount:=0;
 inherited Destroy; 
end;

destructor TElement.Destroy;
 begin
 inherited Destroy;
 end;

только часть пока что.
Re[12]: освобождение памяти при работе с динамическими объек
От: Leonid Troyanovsky  
Дата: 13.09.03 10:06
Оценка:
Здравствуйте, vedmalex, Вы писали:

V>Ок, Привожу часть кода.


V> TLists = class (TElement)


Зачем TLists наследовать от TElement, а не от TObject?
Кстати, мы, вроде бы, договорились приводить такой код,
который может откомпилировать _любой_ без особых напрягов.

V>Деструктор выфглядит следующим образом:


V>destructor TLists.Destroy;

V>var
V> R: TElement;
V>begin
V>if FCount > 0 then
V> while Assigned(Tail) do
V> begin
V> R:=Tail.Next;
V> Tail.Free;

Мне, конечно, трудно судить, что есть Tail, но, судя по именам,
использовать следует Prev, а не Next.V> Tail:=R;

V>только часть пока что.


Именно часть, именно. Никто и не не будет читать случайные обрывки
твоего проекта. Чем больше ты времени потратишь на подготовку
понятного другим кода, тем больше вероятность получить правильный ответ.

Пока же у меня один вопрос, почему ты не использовал вполне обычный TList.
Я не думаю, что он не уложился в те самые минуты на 450 тыс.
Ну и про использование объектов, а не записей пока не видел резонов.

--
С уважением, LVT.
--
С уважением, LVT
Re[13]: освобождение памяти при работе с динамическими объек
От: Аноним  
Дата: 15.09.03 07:11
Оценка:
Здравствуйте, Leonid Troyanovsky
ОК,
Я сделаю, как приеду из командировки,
А по поводу того что список не работает
эти классы работают и это ДеФакто.
почему наследует от TElement — потому что список так же может быть элементом списка
Почему не использовал Tlist — потому как базовые классы
для модели разработаны до меня, но я уже склоняюсь к тому что все переписать все базовые классы под себя а может часть их удалить.
Могу если есть желание переславть полные исходники, все проги.

С Уважением , VEDMALEX.
Re[14]: освобождение памяти при работе с динамическими объек
От: Leonid Troyanovsky  
Дата: 16.09.03 05:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>почему наследует от TElement — потому что список так же может быть элементом списка


Списку нет нужды быть элементом списка, т.к. один список может содержать все ссылки, достаточно снабдить каждый эго элемент идентификатором группы.

Если нужен быстрый доступ к отдельным группам, то можно сделать на основе TList индекс, который будет содержать (отсортированный) список группы.
Можно даже снабдить этот TList методом Find (бинарного поиска), для быстрого позиционирования на ближайший (по критерию) элемент.

А>Почему не использовал Tlist — потому как базовые классы

А>для модели разработаны до меня, но я уже склоняюсь к тому что все переписать все базовые классы под себя а может часть их удалить.

Возможно, что лучший способ разобраться — сделать все самому

А>Могу если есть желание переславть полные исходники, все проги.


Спасибо, конечно, за доверие, однако желания такого не испытываю.
Лучше десять простых вопросов, чем один сложный.

--
С уважением, LVT.
--
С уважением, LVT
Re: освобождение памяти при работе с динамическими объектами
От: vedmalex Россия  
Дата: 24.09.03 14:51
Оценка:
Привет Всем.
Вот я и добрался до рабочего места.
Вроде нашел проблемму она заключается в том что я копирую объекты своей фнкцией.
т.е. в процессе роботы вызываю процедуру COPY.
ошибку нашел с помощью memchck.
кто нить может мне внятно объяснить почем так и как сделать так что бы было нормально
и вообще какие есть методу копирования клонирования объектов.
Вот тут набросал код который генерить исключение.

program Project1;

{$APPTYPE CONSOLE}
uses
  SysUtils,
  MemCheck in 'MemCheck.pas';

type
TElement = class(TObject)
 protected
 Next:TElement;
 Prev:TElement;
 Name : string;
 constructor Create(aName :string);
 function Copy:TClass;virtual;
 procedure CopyVar(var C);virtual;
 end;

RefTClass = Class of Telement;


 TElemDesc = class(TElement)
 HW_Time:Extended;
 CPU_Time:Extended;
 constructor Create(aName:string ;aHW_Time,aCPU_Time:Extended);
 function Copy:TClass;override;
 procedure CopyVar(var C);override;
 end;

 constructor TElement.Create(aName :string);
 begin
 inherited Create;
 Name:=aName;
 end;

 function TElement.Copy:TClass;
 begin
  Result := TClass(TElement.Create(Name));
 end;

 procedure Telement.CopyVar(var C);
 var R:TElement absolute C;
 begin
  r:=TElement.Create(NAme);
 end;

 constructor TElemDEsc.Create(aName:string ;aHW_Time,aCPU_Time:Extended);
 begin
 inherited Create(aName);
 HW_Time:=aHW_Time;
 CPU_Time:=aCPU_Time;
 end;

 function TElemDEsc.Copy:TClass;
 begin
  Result:=TClass(Create(Name,HW_Time,CPU_Time));
 end;
 procedure TElemDesc.CopyVar(var C);
 var R:TElemDEsc absolute C;
 begin
 R:=Create(Name,HW_Time,CPU_Time);
 end;

 var
 i:Integer;
 ElArr:array[0..9] of TElement;
 DEscArr:array[0..9] of TElemDesc;
 El:TElement;
 DEsc:TElemDesc;

begin
//memchk;
Writeln('Creating Base');
//setLength(ElArr,10);
El:=TElement.Create(Format('Elem %D',[1]));
for i:=0 to 9 do
begin
ElArr[i]:=El.Copy;
//El.CopyVar(ElArr[i]);
ElArr[i].Name:=Format('Elem %D',[1]);
end;
Writeln('Creating Descendant');
//setLength(DEscArr,10);
Desc:=TElemDesc.Create(Format('DEsc %D',[1]),100,100);
for i:=0 to 9 do
begin
DescArr[i]:=TElemDEsc(DEsc.Copy);
//desc.CopyVar(DEscArr[i]);
DEscArr[i]:=TElemDesc.Create(Format('DEsc %D',[i]),100,100);
DescArr[i].Name:=Format('DEsc %D',[1]);
end;
writeln('Freeing Arrays Elements');
for i:=0 to 9 do
begin
ElArr[i].Free;
writeln(i);
end;

writeln('Freeing Arrays DEscendant');
for i:=0 to 9 do
begin
DescArr[i].Free; // при втором проходе ошибка
WriteLn(i);
end;

writeln('Freeing vars');
desc.Free;
El.Free;
readln;

end.

как видно пробовал два варианта, но ни один не работает можете убрать коментариии и закоментировать
Можете объяснить в чем трабла
... << RSDN@Home 1.1 beta 1 >>
Re[2]: освобождение памяти при работе с динамическими объект
От: vedmalex Россия  
Дата: 24.09.03 21:44
Оценка:
Так вот небольшая неточность исправлена
в методе TElmDEsc.COPY конструктор вызывался без казания класса
теперь пример выглядит так:
program Project1;

{$APPTYPE CONSOLE}
uses
  SysUtils,classes,
  MemCheck in 'MemCheck.pas';
type
RefTelem = class of TElement;
TElement = class(TObject)
 protected
 Next:TElement;
 Prev:TElement;
 Name : string;
 constructor Create(aName :string);
 function Copy:TElement;virtual;
 end;

 TElemDesc = class(TElement)
 public
 HW_Time:LongWord;
 CPU_Time:LongWord;
 constructor Create(aName:string ;aHW_Time,aCPU_Time:LongWord);
 function Copy:TElement;override;
 end;

 constructor TElement.Create(aName :string);
 begin
 inherited Create;
 Name:=aName;
 end;

 function TElement.Copy:TElement;
 begin
  Result := TElement.Create(Name);
 end;

 constructor TElemDEsc.Create(aName:string ;aHW_Time,aCPU_Time:LongWord);
 begin
 inherited Create(aName);
 HW_Time:=aHW_Time;
 CPU_Time:=aCPU_Time;
 end;

 function TElemDEsc.Copy:TElement;
 begin
  Result:=TElemDesc.Create(Name,HW_Time,CPU_Time);
 end;
 
 var
 i:Integer;
 ElArr:array[0..9] of TElement;
 DEscArr:array[0..9] of TElemDesc;
 El:TElement;
 DEsc:TElemDesc;
 Count:Integer=10;
begin
memchk;
Writeln('Creating Base');
El:=TElement.Create(Format('Elem %D',[1]));

for i:=0 to Count - 1 do
  begin
    ElArr[i]:=El.Copy;
    ElArr[i].Name:=Format('Elem %D',[i+1]);
  end;

Writeln('Creating Descendant');
Desc:=TElemDesc.Create(Format('DEsc %D',[1]),100,100);

for i:=0 to Count - 1  do
  begin
    DescArr[i]:=TElemDesc(DEsc.Copy);
    DescArr[i].Name:=Format('DEsc %D',[i+1]);
    inc(DEscArr[i].HW_Time);
    inc(DEscArr[i].CPU_Time);
  end;

writeln('Freeing Arrays Elements');
for i:=0 to Count - 1 do
  ElArr[i].Free;

writeln('Freeing Arrays DEscendant');
for i:=0 to Count - 1 do
  DescArr[i].Free;

writeln('Freeing vars');
desc.Free;
El.Free;

readln;
end.

мемчек исключений не выдает.
В общем все должно работать и вроде работает так что ищу ошибки в коде своей проги
... << RSDN@Home 1.1 beta 1 >>
Всем спасибо проблему решил пработав с memchek
От: vedmalex Россия  
Дата: 25.09.03 20:07
Оценка:
Собственно САБЖ
http://v.mahon.free.fr/pro/freeware/memcheck/memcheck263.zip
работает для Делфи 7
http://v.mahon.free.fr/pro/freeware/memcheck/tutorial.htm
http://v.mahon.free.fr/pro/freeware/memcheck/faq.htm
И еще раз ОГРОМНОЕ ВСЕМ спасибо .
А ошибочки были в процедурах copy — перетирал классы списков элементов.
... << RSDN@Home 1.1 beta 1 >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.