TObjectListにFreeは不要?

解決


sago  2007-05-02 16:30:22  No: 26003

Delphiを始めたばかりのものです。

TObjectListをつかってオブジェクトの操作をしています。

var
  FooList: TObjectList;
  FooClass: TFooClass;

begin
  :
  FooClass := TFooClass.Create;
  FooList.Add(FooClass);
  :
  :
  FooList.Free;{<-ここで、以上終了、最悪システムがクラッシュします}

TObjectListの廃棄にFreeは不要でしょうか?

非常に初心的な質問で申し訳ありませんが、ご教授をお願いいたします。


遠里 諏我理  2007-05-02 17:15:20  No: 26004

> TObjectListの廃棄にFreeは不要でしょうか?
必要

>   FooList.Add(FooClass);
>   :
    //AddしたものをFreeしている箇所ありませんか?
    FooClass.Free;
>   :
>   FooList.Free;{<-ここで、以上終了、最悪システムがクラッシュします}


creator  2007-05-02 18:22:47  No: 26005

これは
FooList:=TObjectList.create;


sago  2007-05-02 18:49:17  No: 26006

遠里 諏我理様、creator様
ご回答ありがとうございます。

遠里 諏我理様
->一応、「TObjectListは所有しているオブジェクトを廃棄してくれる。」
との記載をみましたので、FooClassを明示的にFreeしている箇所は
ないのです。

creator様
->ご指摘ありがとうございます。
一応、FooList :=  TObjectList.Create;
は記載しています。

FooList.Free;をコメントアウトすると、以上終了、クラッシュは
しないのですが…。

何か他に原因があるのでしょうか?


遠里 諏我理  2007-05-02 23:59:05  No: 26007

※ イカでエラーがでないか
FooClass := TFooClass.Create;
FooClass.Free;

※ TObjectListではなく、TListで使用。
最後は、自分でループを回しながら、FooClass をFreeしてみる。
もちろん、ステップ実行してください。

ちなみに、TFooClass は、具体的に何?
自作クラス?VCLの何か?


sago  2007-05-03 00:20:02  No: 26008

遠里 諏我理様
度々のご回答ありがとうございます。
早速試してみます。
その後、ご報告いたします。

因みにFooClassは自作クラスです。


Mr.XRAY  URL  2007-05-03 07:47:09  No: 26009

この様な問題が発生した場合は,単純なコードで確認するのが定石です.
つまり,問題の切り分けが必要です.
ただ,この場合,必ず「新規作成」のプロジェクトで実験するのが常道です.
(どちらも当たり前ですが,でなければ犯人探しが困難ですからね)
タイトルが「TObjectListにFreeは不要?」となっていますが,Createして使用
したオブジェクトは必ず解放します.

TFooClassが不明なので勝手に作成して実験したコードが以下です.エラーは
でません.メモリの解放忘れもありません.

WindowsXP(SP2) + Delphi7 + FastMM4 で確認
ということは,「TObjectListにFreeは不要?」というDiphiに対する疑惑は晴れる
ことになります.したがって,問題は他のコードにあることになります.
ただし,sago さんの環境で以下のコードで同じ問題が発生するのであれば,間違い
なく環境( Windowsあるいは Delphi ) に問題があります.

type
  //TObjectListはContnrs.pasに

  TFooClass = class(TObject)
  protected
    FNum  : Integer;
    FMoji : String;
  public
    property Num : Integer read FNum write FNum;
    property Moji : String read FMoji write FMoji;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    FooList: TObjectList;
    FooClass: TFooClass;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
     i    : Integer;
     Str1 : String;
     Str2 : String;
begin
     FooList:=TObjectList.Create;

     for i:=0 to 9 do begin
       FooClass:=TFooClass.Create;
       FooList.Add(FooClass);
       TFooClass(FooList.Items[i]).Num:=i*100;
       TFooClass(FooList.Items[i]).Moji:=Chr($41)+IntToStr(i+1);
     end;

     ListBox1.Items.Clear;
     for i:=0 to FooList.Count-1 do begin
       Str1:=Format('%.8d',[TFooClass(FooList.Items[i]).Num]);
       Str2:=TFooClass(FooList.Items[i]).Moji;
       ListBox1.Items.Add(Str1+'    '+Str2);
     end;
end;
//  Createして使用したものは必ず解放
//  アプリ終了時はDelphiが自動的に解放してくれるが,アプリのどこで使用するか
//  不明なので解放した方がメモリの増大を未然に防止可能
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     FooList.Free;
end;


sago  2007-05-03 15:59:01  No: 26010

Mr.XRAY 様
ご丁寧なご回答ありがとうございます。

ご連絡が遅れて大変申し訳ありませんが、遠里 諏我理様にご指摘
いただいたとおり、finally節でFooClassをFreeしておりました…

Mr.XRAY様にご教授いただいた内容は非常に参考になります。
ありがとうございました。

このような私ですが、また何か有りましたらご教授をお願い申し
あげます。


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

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






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