TListに格納したメモリの開放について

解決


maco  2004-05-20 01:38:45  No: 9041

TListを継承し、recordをリスト管理するクラスを作成しています。

RecList (TListを継承して作成したクラスTRecListのインスタンス) で
『値 := RecList.Items[Index].レコードのメンバ変数;』といった感じにrecordにアクセスしたいのです。

しかし、Itemsの戻り値をポインタで無く、TRecord型にしているため、
TRecListに格納しているrecordポインタ型のメモリを開放出来ません。

文書だけでは分かりづらいと思いますので、
以下に簡易版のソースを書きますので、どなたかよい対応方法をご教授下さい。

---------------------------------------------------------------

PRecord = ^TRecord;
TRecord = record
  メンバ省略
end;

type
  TRecList = Class(TList)
  public
    property SetRec();
    property Items[Index : Integer] : TRecord read Get; default;
    procedure Delete(Index : Integer);
end;

function SetRec(); //リスト化するレコードのポインタを格納
var
  Rec : PRecord;
begin
  new(Rec);
  Rec^.メンバ := 格納値;
  TRecList(Self).Add(Rec);
end;

function TRecList.Get(Index : Integer) : TRecord; //Indexのレコードを返す
  Result := PRecord(inherited Get(Index))^;
end;

procedure Delete(Index : Integer);
begin
  Dispose(PRecord(TRecList(Self).Items[Index])); 
    ↑ 
  Itemsの戻り値はTRecord型なのでDispose出来ない!
end;


maco  2004-05-20 01:44:16  No: 9042

質問者です、追記します。

Itemsの戻り値はポインタのまま利用し、
新規プロパティで、ItemsのポインタをTRecordにキャストし、
メンバ変数値を取り出すという方法がベストでしょうか?


るるとん@K  2004-05-20 02:15:35  No: 9043

変数の前に@をつけます


maco  2004-05-20 02:22:36  No: 9044

るるとん@Kさん、返信ありがとうございます。

@は試してみたのですが、「変数が必要です」とエラーが出ます。

Dispose(@(TRecList(Self).Items[Index]));


るるとん@K  2004-05-20 02:26:11  No: 9045

TRecList(Self).Delete[i]
でした


るるとん@K  2004-05-20 02:26:39  No: 9046

ミス
[i]ではなく(i)です


るるとん@K  2004-05-20 02:26:56  No: 9047

ミス
[i]ではなく(i)です


ふぐちゃん  2004-05-20 03:15:48  No: 9048

type
  TRecList = class(TList)
  protected
    function GetItem(Index: Integer): PRecord;
  public
    property Items[Index: Integer]: PRecord read GetItem; default;
  end;

function TRecList.GetItem(Index: Integer): PRecord;
begin
  Result := PRecord(Get(Index));
end;


jok  2004-05-20 03:21:53  No: 9049

> property Items[Index : Integer] : TRecord read Get; default;

これを

property Items[Index : Integer] : PRecord read Get; default;

にすべきです。Get() との整合にもなりますし。

> 『値 := RecList.Items[Index].レコードのメンバ変数;』といった感じにrecordにアクセスしたいのです。

のようにアクセスもできるのでは?


ふぐちゃん  2004-05-20 04:34:16  No: 9050

jokさんのメソッドを再定義する方法の方がきれいですね。
ごみレスを残してすみませんでした。<(_ _)>
ところで、jokさんが答えておられることを言い換えると、

var
  Rec: PRecord;
begin
  New(Rec);
  Rec^.メンバ := 格納値;

の部分ですが、

var
  Rec: PRecord;
begin
  New(Rec);
  Rec.メンバ := 格納値;

のように書けます。
つまり、逆参照演算子は省略できます。
再定義したItemsプロパティを使用する場合についても同様です。


maco  2004-05-20 18:35:50  No: 9051

「ふぐちゃん」さん、「jok」さん
ありがとうございます。

recordのポインタ型では、逆参照なしでもメンバ値を参照できるのですね。

ItemsのGetメソッドの戻り値をPointerからPRecordにすることで、
Deleteメソッド内で、PRecordのメモリの開放も出来ました。

ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加