TList i zwalnianie pamięci po obiekcie

0

Zupełnie nie wiem, czy przypadkiem temat nie nadaje się do 'newbie', ale niestety nie znalazłem nigdzie odpowiedzi na mój problem.

Mam klasę:

type
    TKlasa = class
    public
      int1, int2:integer;
      str1:string;
      constructor Create(i1,i2:integer; s1:string);
    end;

Czyli nic specjalnego.

Chcę jednak utworzyć kilkanaście tysięcy obiektów tego typu. Czynię to dodając każdego do listy TList. Też nie ma problemu.

Problem rodzi się, gdy chcę elementy usunąć z listy lub całkowicie ją wyczyścić. Owszem, obiekty znikają z listy, ale zużycie pamięci w ogóle nie maleje.
Przed stworzeniem obiektów program zajmuje 70MB w ramie, po stworzeniu jakieś 500 MB.
Robię lista.clear; - lista jest wyczyszczona, ale program nadal zżera 500 MB... To samo gdy każdy obiekt usuwam z listy samodzielnie (lista.delete(indeks)).

Domyślam się, że lista przechowuje tylko wskaźniki do obiektów, a więc z listy usuwam konkretnie wskaźnik.
Teraz jak rozwiązać problem niezwalniania pamięci? Jak napisać destructor do tej klasy: co powinien zawierać w sobie?

0

a może byś tak łaskawie zwolnił stworzone obiekty

0

w takim razie proszę o podpowiedź: jak?
bo właśnie o to pytam.

0

:| nie czytales o konstruktorach i destruktorach...? przeciez to podstawa.
musisz zwolnic wszystkie obiekty ktore utworzyles.

2

Nie sprawdziłem czy na pewno ale wydaje mi się że powinno działać:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TKlasa = class
  private
    fInt1, fInt2:integer;
    fStr1: string;
  public
    constructor Create(i1,i2:integer; s1:string);
    property Int1: Integer read fInt1 write fInt1;
    property Int2: Integer read fInt2 write fInt2;
    property Str1: string read fStr1 write fStr1;
  end;

  TMyObjList = class(TList)
  public
    procedure Delete(Index: Integer);
    procedure Clear; override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    MyObjList: TMyObjList;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TKlasa.Create(i1,i2:integer; s1:string);
begin
  fInt1:= i1;
  fInt2:= i2;
  fStr1:= s1;
end;

procedure TMyObjList.Delete(index: Integer);
begin
  TKlasa(Items[index]).Free;
  inherited Delete(index);
end;

procedure TMyObjList.Clear;
begin
  while Count > 0 do
    Delete(0);
  inherited Clear;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
  Obj: TKlasa;
  i: Integer;
begin
  MyObjList:= TMyObjList.Create;
  for i:= 0 to 100000 do
  begin
    Obj:= TKlasa.Create(i, i, IntToStr(i));
    MyObjList.Add(Obj);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject); //delete (tu akurat czyszczenia przez Delete kolejnych)
begin
  while MyObjList.Count > 0 do
    MyObjList.Delete(0);
end;

procedure TForm1.Button2Click(Sender: TObject); //czyszczenie
begin
  MyObjList.Clear; //poprzedzone naszym delete
end;

procedure TForm1.Button3Click(Sender: TObject); //zwolnienie
begin
  MyObjList.Free; //tu zostanie automatycznie wywołane clear a z nim nasze delete  
end;

end.
0

i tym samym dziękuję kAzek ;))

1

kAzek ja wiem, że fajnie jest wymyślać koło od nowa ale programiści Borlanda wpadli już na pomysł, że może jednak komuś się przyda lista, która sama zwalnia swoje obiekty - nazywa się ona TObjectList i znajduje się w module Contnrs.
BTW lista (TList) ma coś takiego jak Notify, które jak już to należy nadpisać i tam zwalniać obiekty

1 użytkowników online, w tym zalogowanych: 0, gości: 1