スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Releaseモードで強制終了するバグの原因が分かった!! (DirectX)

以前、Releaseモードで原因不明の強制終了が発生して、
とんでもなく苦悩したんですが、

原因が分かりました。
実に・・・実に初歩的なことだった・・・!

原因はCOMオブジェクトです。
大まかに"COMオブジェクト"の説明をします。

~COMオブジェクトの特徴~   -------------------------------------------
・独自の生成、解放などに関するメソッド(関数)が用意されているので、
 それを使用する。 中身はブラックボックス。
・COMオブジェクトがコピーされる際、AddRef関数を明示的に呼び出さねばならない。
・デバッグモードでも、COMオブジェクトの解放忘れは検出されない

※以下のメモリリーク検出するコードを記載していても無意味。
プログラムは正常に終了しましたと表示される。

#if _DEBUG
#include
#define new ::new( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF, __FILE__, __LINE__ )
#endif
-----------------------------------------------------------------------

んで、バグの原因について。

端的に言います。
AddRef関数を呼んでませんでした。

ラッパークラスを作っており、
コピーコンストラクタは定義してたんですが、
演算子のオーバーロードを忘れてました。

↓こんな感じ。 コレまるごと記載していなかった。
   void operator =(const CTexture& src){
//バッファのコピー処理
if(src.m_Buf){
src.m_Buf->AddRef();
}
if(this->m_Buf){
this->m_Buf->Release();
}
//テクスチャのコピー処理
if(src.m_Texture){
src.m_Texture->AddRef();
}
if(this->m_Texture){
m_Texture->Release();
m_Texture = NULL;
}

m_Texture = src.m_Texture;
m_Buf = src.m_Buf;
}


↓以下のコピーコンストラクタは定義してたんですけども。
CTexture::CTexture(const CTexture &src)
{
//バッファのコピー処理
if(src.m_Buf){
src.m_Buf->AddRef();
}
if(this->m_Buf){
this->m_Buf->Release();
}
//テクスチャのコピー処理
if(src.m_Texture){
src.m_Texture->AddRef();
}
if(this->m_Texture){
m_Texture->Release();
m_Texture = NULL;
}

m_Texture = src.m_Texture;
m_Buf = src.m_Buf;
}


まぁ、という訳で、
参照カウントが滅茶苦茶になっていたと思われます。

まだ参照してる箇所があるのに、カウントが0になって解放されてたり、
もう参照している箇所は無いのに、カウントが1のままで、解放されない状態だったりして、
壊れてたんだと思います。
(ダングリングポインタ & リソースリーク)


とりあえず修正したところ、
ものの見事にバグが発生しなくなりました。
最高です。

もっとDirectXの基礎的な仕様を把握せにゃならんな、と思いました。
スポンサーサイト

テーマ : 日記 - ジャンル : 日記

コメント

追記

 rssリーダーから来る場合、後から追記するとrssには追加として扱われないので、それに気付くのは次に記事を追加したときなんですよね……。

No title

なんと そうでしたか!v-404
記事が完成するまで「下書き」 ⇒
記事が完成して「公開」 に変更
した方が良さそうですねv-292

次からは、一気に記事全文をUPする形にしたいと思います!
(`・ω・´;)

No title

> 一気に記事全文をUPする形
 ありがとうございます。
 そうしていただけると助かります。

> AddRef関数を明示的に呼び出さねばならない
  CComPtrとかboost::intrusive_ptrは使えない環境でしょうか?

No title

最近までCComPtrなどについて知りませんでした(´・ω・`)
(SharedPtrは使っていたんですけども)

色んなスマートポインタがあるものですねv-293

おおまかに、リファレンス的なものも覚える必要があるとは思いますが、
とりあえずCComPtrを使っての実装をやってみたいと思います!
情報ありがとうございます!v-411

あと、COMオブジェクトの解放忘れの検出方法もあるっぽいですね。
(DirectX Control Panelで設定をする)

潜在的にバグっているかを 把握できると便利ですし、
こちらも同時に試してみたいと思いますv-290
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。