使用されなかったHDC等の解放および削除

[戻る]
Air 2004/11/07(日) 22:23:08
いつもお世話になっております。
前スレの続きになりますが、改めて説明させていただきます。

基本となるビュークラスに、メンバ変数として
HDC および HBITMAP を持っております。
これらは、画像の読み込みがあったときに、その画像をピクチャボックスに
表示する用に宣言しています。
解放および削除は、同じくビュークラスのデストラクタで行っております。

::DeleteObject(m_pic_compatiDC);  // HDC
::DeleteObject(m_pic_DIB);        // HBITMAP
::ReleaseDC(m_pic_hDC);           // HDC

といった具合です。
お聞きしたい事は、画像が一度も読みこまなければ、これらの変数は宣言されただけで
一度も使われる事はありません。
ですが、この解放部分はデストラクタなので100%通ります。
これはやっぱりまずいのでしょうか?

ご助言よろしくお願い致します。

瀬戸っぷ [E-Mail] 2004/11/07(日) 22:48:57
ポインタ等でよく取られるパターンとしてNULLで初期化して、
解放時にNULLか否かで処理を分ける。というのがありますね。

が……MFCを使用されているようですし、
CDCやCBitmapをクラスのメンバにした方が楽なのではないでしょうか?
それぞれのクラスのデストラクタで破棄してくれるでしょうし。
(SelectObjectには注意が必要なのかな。)

ゆう 2004/11/08(月) 03:20:38
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200411/04110014.txt
こちらからの流れなら...

new(やmalloc)した物は一回も使わなくてもdelete(やfree)しなくてはいけませんよね。
でも、ポインタを作っただけで一回もnew(malloc)しなければ、delete(free)しなくても
かまいません。

ポインタに相当する物がHXX(いわゆるHANDLE)であり、CreateXXはnew(malloc)に相当します。
ですからCreateXXしたら当然DeleteXX(deleteやfree相当)しなければいけません。
その内容を使うかどうかは関係ありません。
作ったかどうかがが問題になります。

HBITMAPを宣言しただけなら、何もしなくても良いですが、CreateDIBSectionしてしまったら、
必ずDeleteObjectしましょう。

ちなみに、間違ってます。
>::DeleteObject(m_pic_compatiDC);  // HDC
DeleteDCです。

Air 2004/11/08(月) 14:45:45
ご返答ありがとうございます。

瀬戸っぷさんの言われる、CDC と CBitmap に関して
余裕があれば、改良してみようと思います。
貴重なご意見ありがとうございます。

Create は new に相当ですか、なるほど。わかりやすいです。
てことは、やっぱり作成されてないものに Delete なり Release なりは
まずい感じがしますね。
というか、new と delete の関係ならハングですよね・・・

瀬戸っぷさんの言われてるとおり、普通のポインタなら
if ( OOO == NULL ) で簡単なんですがね。
HDC とか HBITMAP だとどうなるんでしょう・・・ 別にフラグなりを用意して
作成されたらフラグ立てて、デストラクタでフラグを見て解放or削除
となるんでしょうかね?
みなさんは、どのようにされてるんでしょうか?
ご意見お聞かせいただければありがたいです。

よろしくお願いします。

PATIO 2004/11/08(月) 14:51:51
HDCにしてもHBITMAPにしても無効値というのが設定してあります。
実際にはCreateに失敗すればそれが返ってきているはずです。
普通こういう変数の初期値はこの無効値を使います。
デストラクタでは無効値無ければ、Closeするような処理すれば良いわけです。
このやり方は常套手段なので覚えておいた方が良いです。

また、こういう処理の流れにする時はその値の無効値を調べるのが常套手段です。
覚えておいた方がいいと思いますよ。

Air 2004/11/08(月) 14:53:19
連続書き込みすいません、忘れていたことが。

何度も質問させていただいてるのに、今更開発環境を書き忘れてました。
察してくれた瀬戸っぷさんに感謝です。

[ 開発環境 ]
Windows XP
VC++ 6.0 MFC  です。

それと、間違いを指摘してくださったゆうさん、ありがとうございます。
( 実は参考書がこうなってるんですよ・・・ 犠牲者多数? )

Air 2004/11/08(月) 15:22:04
ご返答ありがとうございます。

無効値、初めて聞く単語です。
さっそく、Create部分を無理やり失敗するようにして、調べてみました。
全て0が返ってきていました。
ということは

// 宣言部
HDC     m_hdc;
HBITMAP m_bm;

// コンストラクタ
m_hdc = 0;
m_bm = 0;

// デストラクタ
if( m_hdc == 0 )
   DeleteDC(m_hdc);

if(m_bm == 0)
   DeleteObject(m_bm);

といった具合でしょうか?
それとも、0ではなく、ポインタと考えて NULL の方がいいんでしょうか?

そしてふと思ったんですが、
ReleaseDC と DeleteDC って、これは両方呼ぶべきなんでしょうか?
今は片方しか呼んでませんが。

よろしくお願いします。

REE 2004/11/08(月) 15:51:14
>無効値、初めて聞く単語です。
>さっそく、Create部分を無理やり失敗するようにして、調べてみました。

こういう情報は、MSDNなどのその関数の説明で確認しましょう


>ReleaseDC と DeleteDC って、これは両方呼ぶべきなんでしょうか?
>今は片方しか呼んでませんが。

こういう情報も、MSDNなどで調べることが出来ます。
ちなみに、片方だけ呼ぶのが正しいです。

PATIO 2004/11/08(月) 17:06:02
兎にも角にもVisualStudio付属のHELP(これもMSDNです)か
オンラインのMSDNで調べる癖をつけましょう。
取り敢えずやってみるってのも手なんですが、効率が悪すぎますので。
MSDNでもはっきりしないような事は、実際にテストプログラムを作って
試した方が早いと言う場合もありますけれど、
今回のような情報はMSDNで調べればすぐに出てきます。

まあ癖があると言えばありますけれど、Microsoftが出している公式な資料ですし、
内容的にはかなりの物が入っています。これをまず調べない手はありません。
慣れは必要ですが、慣れるだけの価値はあると思いますので最初のうちは
調べにくいかもしれませんが、辛抱して使う事をお勧めします。

PATIO 2004/11/08(月) 17:08:09
因みにこういう無効値は定数定義してある事が多いので
どういう定義がしてあるのか調べて定義してある物を使った方が良いです。

Air 2004/11/08(月) 17:37:28
[[解決]]
ご返答ありがとうございます。

言われたとおり、MSDNで調べてみました。
どれも作成等に失敗したときはNULLを返すとなっているので
それを初期化と解放(削除)の条件にしてやってみようと思います。
まだVC++初心者ということで、ややとっつきにくいマニュアルなのですが
がんばってみます。

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

古いスレッドには追加発言できません。