オブジェクトの破棄について

解決


るるとん@K  2004-03-27 04:38:24  No: 7925

オブジェクトを破棄し忘れても(例えばですが)、
アプリケーション終了時に破棄してくれますか?
OwnerがApplicationとかなので破棄されるんですか?


jok  2004-03-27 05:14:43  No: 7926

>オブジェクトを破棄し忘れても(例えばですが)、
>アプリケーション終了時に破棄してくれますか?

これは微妙な問題です。OSのバージョンにもよります。わたしが昔経験したのでは
TBrush のインスタンスをいっぱいつくって解放しわすれたとき、Windows95 では
アプリケーションを終了させてもGDIリソースが回復しませんでした。再起動が必要
でした。Win9X系では、GDIリソースが共通領域にとられるようです。NT系でし
たら多分アプリの終了とともにリソースも解放されるでしょう。でも、プログラマ
は、あくまでコードで完結するように書くべきだと思います。

> OwnerがApplicationとかなので破棄されるんですか?

たとえば、Form1 に Panel1 とその上に Button1 を置いたプログラムをつくった
とします。Panel1 と Button1 は TComponent の派生クラスなので、自動的に
IDE はオーナーを Form1 にしてインスタンスを生成します。また、プロジェクト
ファイルのコードで生成される Form1 のオーナーは Application です。
Application オブジェクトは、アプリ終了時に VCL のコードで破棄されます。
そしてそのまえに、所有している Form1 を破棄します。Form1 は自分が破棄され
るまえに、所有している Panel1 と Button1 を破棄します。このようにして、
芋蔓式にはきされるので、オーナを適正に設定されているときは、そのオブ
ジェクトの破棄について心配する必要はありません。コードで Free することも
できます。


tomo  2004-03-27 05:31:29  No: 7927

>オブジェクトを破棄し忘れても(例えばですが)、
>アプリケーション終了時に破棄してくれますか?
一般的に開放し忘れたオブジェクトは正常には破棄されません。
OSが開放するのはあくまでメモリやリソースであって
TObjectから派生したオブジェクトではありません。
ですのでオブジェクトのデストラクタDestroyが呼ばれません。
# Delphi8では.NET Frameworkが自動的に開放してくれるはずですが。

プログラム終了時に、開放し忘れたオブジェクトがあるかどうかを検出するライブラリがあるので
デバッグ中は常にチェックしておくことをお勧めします。
http://www.google.com/search?hl=ja&ie=UTF-8&oe=UTF-8&q=MemCheck+Delphi&lr=lang_ja


jok  2004-03-27 06:01:23  No: 7928

> 一般的に開放し忘れたオブジェクトは正常には破棄されません。
> OSが開放するのはあくまでメモリやリソースであって
> TObjectから派生したオブジェクトではありません。
> ですのでオブジェクトのデストラクタDestroyが呼ばれません。

うーむ、これの説明がわかりません。TObject の派生クラスのインスタンスは
メモリ上に作成されるんじゃないですか? デストラクタが実行されなくても
アプリが終了するとき解放されるのではないでしょうか。
もちろん、それを期待したコードは正しくはありませんが。

MemCheck はデバッグ用のユニットですよね? 使ったことはないですけど。
アプリ終了時にコードで解放し忘れたのを検出するものと理解しています。
アプリ終了してしまったあとに残っているかどうかはどうやって知るのでしょうか。


tomo  2004-03-27 07:02:13  No: 7929

>TObject の派生クラスのインスタンスは
>メモリ上に作成されるんじゃないですか? デストラクタが実行されなくても
>アプリが終了するとき解放されるのではないでしょうか。
そのとおりです。
問題になるのはそのオブジェクトのデストラクタでメモリ開放以外の処理を記述していた場合
# 例えばオブジェクトのデータをINIファイルに保存するなど
その処理が行われない事です。

>アプリ終了してしまったあとに残っているかどうかはどうやって知るのでしょうか。
正確に言うと終了する直前です。
MemCheckユニットのfinalization部分でチェックします。


jok  2004-03-27 07:27:35  No: 7930

回答ありがとうございます。
元質問は

> アプリケーション終了時に破棄してくれますか?

ですので、普通は大丈夫とのことですね?

>>アプリ終了してしまったあとに残っているかどうかはどうやって知るのでしょうか。
>正確に言うと終了する直前です。
>MemCheckユニットのfinalization部分でチェックします。

あ、いや、MemCheck の仕組みではなく、質問のとおり<終了後>の確認はどうする
のか、ですけど.....


tomo  2004-03-27 08:30:36  No: 7931

>普通は大丈夫とのことですね?
るるとん@Kさんへは、オブジェクトは破棄されないと回答しました。
具体的な挙動と問題となるケースは上で説明したとおりです。

>質問のとおり<終了後>の確認はどうする
>のか、ですけど.....
メモリリークが発生した場合のユーザーへの通知は
Windows.MessageBoxで行われます。


jok  2004-03-27 09:15:30  No: 7932

回答ありがとうございます。

>るるとん@Kさんへは、オブジェクトは破棄されないと回答しました。
>具体的な挙動と問題となるケースは上で説明したとおりです。

質問の内容にもよりますが、tomoさんはデストラクタが実行されるかいなかを、
わたしはメモリが解放されるかいなか、を問題にしているのだと思います。


るるとん@K  2004-03-27 21:03:12  No: 7933

よく分かりました。
jokさんtomoさんありがとうございました。


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

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






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