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

解決


maco  2004-05-20 01:38:45  No: 9041  IP: [192.*.*.*]

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  IP: [192.*.*.*]

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

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

編集    削除
るるとん@K  2004-05-20 02:15:35  No: 9043  IP: [192.*.*.*]

変数の前に@をつけます

編集    削除
maco  2004-05-20 02:22:36  No: 9044  IP: [192.*.*.*]

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

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

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

編集    削除
るるとん@K  2004-05-20 02:26:11  No: 9045  IP: [192.*.*.*]

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

編集    削除
るるとん@K  2004-05-20 02:26:39  No: 9046  IP: [192.*.*.*]

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

編集    削除
るるとん@K  2004-05-20 02:26:56  No: 9047  IP: [192.*.*.*]

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

編集    削除
ふぐちゃん  2004-05-20 03:15:48  No: 9048  IP: [192.*.*.*]

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  IP: [192.*.*.*]

> 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  IP: [192.*.*.*]

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  IP: [192.*.*.*]

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

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

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

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

編集    削除