メモリの解放について

解決


ペレ  2005-11-21 22:38:08  No: 18840  IP: 192.*.*.*

iniファイルから値を取得するプログラムを作成しているのですが、プログラム内で頻繁にiniファイルを読み書きするためprivateにIniを宣言しています。

プログラム内で「Ini := TMemIniFile.Create('C:\test.ini');」で何回かIniオブジェクトを生成して、最後にFormDestroyでまとめてIniオブジェクトを解放しようとしたのですが、下記の例で言う①のIniオブジェクトのメモリが解放されません。(②のIniオブジェクトだけ解放されます)

FormDestroyで①と②のIniオブジェクトを解放するには、
どうしたら良いのでしょうか?

1回1回Ini.Freeで解放しろと言われればそれまでですが、
Createしている箇所が多いためFormDestroyでまとめて解放出来ないかと
思った次第です。

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Ini: TMemIniFile;
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation
  
procedure TForm1.Button1Click(Sender: TObject);
var
  strIni1: String;
  strIni2: String;
begin
  Ini     := TMemIniFile.Create('C:\test.ini');         …  ①
  strIni1 := Ini.ReadString('Section', 'Key1', '');
  
  Ini     := TMemIniFile.Create('C:\test.ini');         …  ②
  strIni2 := Ini.ReadString('Section', 'Key2', '');  
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Ini.Free;
end;

編集 削除
意味わからん  2005-11-21 22:46:17  No: 18841  IP: 192.*.*.*

1と2の二つ分の変数用意すればいいだけでしょ?

編集 削除
りおりお  2005-11-21 22:47:32  No: 18842  IP: 192.*.*.*

② はいらないんじゃないですか。同じ変数に入れてるから、先に入れたほうが行方不明になるのでは。

>1回1回Ini.Freeで解放しろと言われればそれまでですが、
>Createしている箇所が多いためFormDestroyでまとめて解放出来ないかと
>思った次第です。

いちいち Free するのがこういう場合の基本だと思います。Create と同じ回数
Free しないとリークするのは当然です。

編集 削除
りおりお  2005-11-21 23:13:31  No: 18843  IP: 192.*.*.*

ini ファイルが一つだけなら

FormCreate で一回だけ Create して、使い回し、FormDestroy で Free するといいです。

編集 削除
ペレ  2005-11-21 23:35:21  No: 18844  IP: 192.*.*.*

例が悪くて言いたいことをうまく伝えれず、すみません。先例は忘れて下さい。
本当にやりたいことは、りおりおさんが言うとおりFormCreateでIniを生成してFormDestroyでIniを解放したいだけです。
しかし、②でIniファイルの内容を頻繁に更新した後、③で最新の値が取得出来なかったので、③の前に「Ini := TMemIniFile.Create('C:\test.ini');」を追加したのですが、①が解放されません。

ちなみに、上記の代わりに「Ini.UpdateFile」にしても③で最新の値が取得出来ませんでした。

>② はいらないんじゃないですか。同じ変数に入れてるから、先に入れたほうが行方不明になるのでは。
行方不明になったオブジェクトを解放することは不可能なのですか?

procedure TForm1.FormCreate(Sender: TObject);
begin
  Ini := TMemIniFile.Create('C:\test.ini');          ・・・①
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  strIni1: String;
  strIni2: String;
begin  
  strIni1 := Ini.ReadString('Section', 'Key1', '');
  
  -------------------------------
  Iniファイルに読み書きを行う                        ・・・②
  -------------------------------

  Ini := TMemIniFile.Create('C:\test.ini');
  strIni2 := Ini.ReadString('Section', 'Key2', '');  ・・・③
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Ini.Free;
end;

編集 削除
もしかして  2005-11-22 08:39:20  No: 18845  IP: 192.*.*.*

-------------------------------
  Iniファイルに読み書きを行う                        ・・・②
  -------------------------------

  //これが必要かね?
  Ini.UpdateFile;

  //Ini := TMemIniFile.Create('C:\test.ini');
  strIni2 := Ini.ReadString('Section', 'Key2', '');  ・・・③

編集 削除
Syake  2005-11-22 08:42:27  No: 18846  IP: 192.*.*.*

①やった後に③の記述は駄目ですよね。
って皆書いてますよね。

根本的に何をされたいのか良くわかりませんが
Iniファイルは前回起動時内容を保持させ次回起動時その内容を反映させたい
とか、ユーザー毎に何らかの初期値を保持させたい等の時に利用するもんだ
ろうと思っとります。
>プログラム内で頻繁にiniファイルを読み書きするため
何でこんな必要があるのかな?と、勝手に解釈しとります。

私なら
①アプリ起動時にIniファイルの内容を一気に何らかの変数に読み込む
②アプリ終了時にその変数値をIniファイルに書き戻します。
アプリ実行中はその変数の値を書き換え・参照するだけですみます。
そうしたら、その様な記述は無くて済みます。

編集 削除
ペレ  2005-11-22 11:57:21  No: 18847  IP: 192.*.*.*

みなさん返信ありがとうございます。

みなさんの言われる通り、Iniの使いまわしせずに
下記のように1回1回解放するようにします。
ご迷惑をおかけしました。

Ini := TMemIniFile.Create('C:\test.ini');
try       
     
except    
 Ini.Free;  
end;

>//これが必要かね?
>Ini.UpdateFile;
これでちゃんと更新がかかってくれれば問題なかったのですが、
ダメだったので、「Ini := TMemIniFile.Create('C:\test.ini');」のようにしています。

編集 削除
Fusa  2005-11-25 00:31:23  No: 18848  IP: 192.*.*.*

普通こうですよ。
Ini := TMemIniFile.Create('C:\test.ini');
try       

finally     
 Ini.Free;  
end;

TMemIniFileの場合、Freeの前に
 Ini.UpdateFile;
を行った方がいいですね。

編集 削除
ペレ  2005-11-25 13:35:32  No: 18849  IP: 192.*.*.*

失礼しました。
exceptではなくfinally でした。

>TMemIniFileの場合、Freeの前に
>Ini.UpdateFile;
>を行った方がいいですね。
こういうことですか?
Ini := TMemIniFile.Create('C:\test.ini');
try       

finally     
 Ini.UpdateFile;
 Ini.Free;  
end;

Iniを解放する前に更新した方が良いということですか?
どういうメリットがあるのでしょうか?

編集 削除
Fusa  2005-11-25 22:48:01  No: 18850  IP: 192.*.*.*

メリットというか、Ini.WriteStringとか
Write系のものを使った時
TIniFileは即時実行ですが
TMemIniFileは
UpdateFileを使わないと更新されなかった
気がしますよ。

編集 削除