お世話になります。環境はWindows XP Pro Delphi 6 Personalです。
質問1:素人が作成したプログラムだからメモリーリークがあるだろ〜な〜とは考えていましたが、ふとしたきっかけでメモリーリークをチェックできるソフトを下記のサイトで見つけました。
そこで実行してみると2700個(TreeViewの要素数と同じ)くらいチェックに引っかかり仰天しました。下記のNew()を外すとほぼ0になります。
コードはお気に入りをテキストファイルに保存していて、それを起動時にTreeViewにロードするとき発生するのが判りました。
ヘルプにNew()を使ったらDispose()で解放することと書いてありましたから、適当と考えられる場所にいれるとリークは0になりますが TreeViewのNodeのURLが空白で入るようでうまくいきません。
TreeViewに要素名+URLを登録するサイトは散見するのですがDisposeを書いてあるのを見かけません。不要なのでしょうか?
質問2:以前この掲示板には過去ログ検索が合ったような気がするのですが見あたりません。ブラウザがおかしいのかといろいろ試しました。なぜ無くなったのでしょうか?大変お世話になっていたので残念です。
よろしくお願いします。
TOBY SOFT wiki の Delphi メモリーリークをチェックするの HeapChecker
http://tobysoft.net/wiki/index.php?Delphi%2F%A5%E1%A5%E2%A5%EA%A5%EA%A1%BC%A5%AF%A4%F2%A5%C1%A5%A7%A5%C3%A5%AF%A4%B9%A4%EB
type
PBookMarkItem = ^TBookMarkItem;
TBookMarkItem = record
URL:string;
end;
・・・・
var
P:PBookMarkItem;
Node:TTreeNode;
StringListNode, strList :TStringList;
begin
・・・・
//お気に入りテキストファイルをロードする 構造 "level","要素名","http://......URL"
StringListNode.LoadFromFile(AppPath+'ScrapbookData\_ScrapBookSystem\IEFavorites.txt');
OldLevel := 0; //integer
Node := nil; //
for i := 0 to StringListNode.Count -1 do
begin
StrList.CommaText := StringListNode.Strings[i];
NewLevel := StrToInt(StrList.Strings[0]) ; //レベル
strTitle := StrList.Strings[1]; //項目名
New(P);
P^.URL := StrList.Strings[2]; //URL
Node := formMDI.TreeView1.Items.AddObject(Node,strTitle,P)
if OldLevel > NewLevel then
begin
OldLevel := NewLevel;
while Node.Level > NewLevel do
begin
Node.MoveTo(Node.Parent,naAdd);
end;
end
else
begin
if OldLevel < NewLevel then //子にする
begin
Node.MoveTo(Node.GetPrev,naAddChild);
OldLevel := NewLevel;
end;
end;
Dispose(P);//・・・・・・・・・此処に入れてみましたがURLがクリアーされるみたい
end;
TStringListには、Pのアドレスが入りますので、すぐに
Disposeすると、TStringListの中身がなくなります。TStringListを開放するときにDisposeしましょう。
HOtaさん、さっそく教えて頂きありがとうございました。
これで悩みが一つ消えます。
さっそく実行させてもらいます。
では。
このコードの終了時、StringListNode.FreeのあとにDispose(P);を実行したのですが効果はありませんでした。
引き続き勉強してみます。
では。
Freeしてしまうと、DisposeするPのアドレスもなくなります。
Freeの前ですよ。
Disposeの前に
P^.URL:= '';
も必要だと思います。
後、解放のタイミングはTTreeViewの各NodeのDataプロパティが必要で無くなった時です。
HOtaさん、Basser さん、ありがとうございます。
ずっとトライしているのですが、起動時にTreeViewにここでお気に入りを登録して、先のコードのあとは
・・・
finally
P^.URL:= '';
Dispose(P);
StringListNode.Free;
strList.Free;
end;
end;
で終わるだけですが、起動中はお気に入りをずっと使います。
前記のように記述してプログラムを終了すると「約2700個のヒープ領域が未解放です」と出るのですがこれは異常では無いのでしょうか?
記述場所が悪いのでしょうか?
ちなみに、繰り返しルーチンの中に入れるとURLは空になる代わりにヒープ領域の未解放は0になります。
できればよろしくお願いいたします。
>前記のように記述してプログラムを終了すると「約2700個のヒープ領域が未解放です」と出るのですがこれは異常では無いのでしょうか?
それは以上、...でなくて、異常。
>記述場所が悪いのでしょうか?
記述場所は OnDeletionハンドラ。
使っている間は、開放すると無くなりますから、しません。
この場合なら、プログラムの終了時に開放します。
春場所さん、HOtaさんありがとうございます。
やっとわかりました。
プログラムの後始末についていままで真剣に考慮していませんでした。
いい勉強になりました。ありがとうございました。
では。
ツイート | ![]() |