• 締切済み

メモリーかな?

ひそひそと小規模なげーむを作っております。 実はノベルゲームのような文字がたくさん出るようにしたくて DirectX技術編というサイトを参考にしまして、テクスチャ文字を 一文字作成するclassをつくりまして、それを派生させて、自分なりの 会話表示に使う分を出力するクラスをつくりました。 ここまではよかったのですが、それを使っていると不具合が出ました。 はじめのマップ1でキャラクター人数分の会話文の文字作成を行い、 マップ1からマップ2に移動することで、マップ1で作成した文生成 のクラスをdelete。 次にマップ2のキャラクターの会話文を生成。ここまでは不具合なく 問題はなかったのですが、マップ1とマップ2を行き来することで 文字の破棄と生成を繰り返すことで、アプリケーションが強制終了 の状況に追い込まれました。 何度か試して、最初に一括して文の文字を生成して生成と破棄を繰り返さなければ問題はでませんでした。 問題が発生してとまる部分はいつも、文字作成部分の TEXTMETRIC TM; GetTextMetrics( hdc, &TM ); GLYPHMETRICS GM; CONST MAT2 Mat = {{0,1},{0,0},{0,0},{0,1}}; DWORD size = GetGlyphOutline(hdc, code, GGO_GRAY4_BITMAP, &GM, 0, NULL, &Mat); BYTE *ptr = new BYTE[size]; GetGlyphOutline(hdc, _T(code), GGO_GRAY4_BITMAP, &GM, size, ptr, &Mat); の、BYTE *ptr= new BYTE[size]の部分でした。 おそらく自分なりの考えではメモリー容量とかんけいしているのかな とおもったんですけど、詳しい方どうかお願いします。 僕のパソコンはメモリー256MBです。 こんな文字の出力はゲームボーイでもできたのに、やはりメモリー ではなくて、自分の非効率なプログラムのせいでしょうか…。 メモリーリークは出ていません。

みんなの回答

回答No.2

 こんにちは。  STLを使用して良いのならば、BYTE* ptr = new BYTE[size]; を std::vector<BYTE> buf(size); に置き換えて使用するなど。  文字列系のwin32apiはモノによって'\0'文字を含んで返してきたり、そうで無かったりと、まちまちです。  std::basic_string を直接的な受け皿に使用すると痛い目に合うので std::vector を仲介した方が得策です。  その他、 #include<set> class CTextBuffer { typedef std::set<BYTE*> SetPtr; static SetPtr _S_set; public: static BYTE* Create(DWORD size) { if(size == 0)return NULL; BYTE* p = new BYTE[size]; //ポインタの登録 _S_set.insert(p); return p; } static INT Release(BYTE* p) { SetPtr::iterator it = _S_set.find(p); //2重解放の検出 if(it == _S_set.end()) { ::MessageBox(NULL, "トラブル発生", "2重解放,または関係ないポインタ", IDOK); return -1; } _S_set.erase(it); delete[] p; return _S_set.size(); } static BOOL IsMemoryLeak() { return !_S_set.empty(); } //其の他色々な関数(例えば、全部消すなど) }; CTextBuffer::SetPtr CTextBuffer::_S_set;  の様にして TEXTMETRIC TM; GetTextMetrics( hdc, &TM ); GLYPHMETRICS GM; CONST MAT2 Mat = {{0,1},{0,0},{0,0},{0,1}}; DWORD size = GetGlyphOutline(hdc, code, GGO_GRAY4_BITMAP, &GM, 0, NULL, &Mat); //以下の様にする BYTE *ptr = CTextBuffer::Create(size); GetGlyphOutline(hdc, _T(code), GGO_GRAY4_BITMAP, &GM, size, ptr, &Mat);  と言った具合で使用して行くとか。  其の他に考えられるのは、HDC辺りの解放漏れでしょうか。

kaijinu-un
質問者

お礼

なるほど~、APIにはそのような落とし穴が用意されていようとは。 根本的にAPIの知識不足から招いたエラーのような気がしてきました。 プログラム方法を参考にして、もう一度考え直してみることにします。 ありがとうございました。 ちなみに、HDCはちゃんと開放してます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そこで new[] でメモリを確保した ptr は, きちんと delete[] で解放してますか? 複数回 delete[] するような実行経路は存在しませんか? 「メモリーリークは出ていません」と書かれていますが, きちんと確認しましたか?

kaijinu-un
質問者

お礼

えっと、一文字作成し終えたら、 #define SAFE_ARRAY_DELETE(p) if(p){ delete [] p; p=0;} で削除していますので、配列消去はできていると思います。 もう一度二重開放していないか経路を探索してみたいと思います。 メモリー開放のほうは、 #ifndef _DENUG_H_ #define _DEBUG_H_ #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #ifdef _DEBUG #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif #endif を使ってチェックしたので大丈夫だ思うのですが。

関連するQ&A