デバッグ ヒープ上のメモリ ブロックの型
このトピックの内容は、次の製品に該当します。
エディション |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
ネイティブのみ |
||||
Pro、Premium、Ultimate |
ネイティブのみ |
デバッグ ヒープ上のすべてのメモリ ブロックには、5 つの割り当て型のうちのいずれかの型が割り当てられます。 型によって、メモリ リークの検出やメモリ状態をレポートするときの追跡方法やレポート方法が異なります。 メモリ ブロックの型を指定するには、_malloc_dbg などのデバッグ ヒープ割り当て関数を直接呼び出してメモリ ブロックを割り当てます。 デバッグ ヒープ上のメモリ ブロックの 5 つの型を次に示します。これらの型は、_CrtMemBlockHeader 構造体の nBlockUse メンバーに設定されます。
_NORMAL_BLOCK
malloc または calloc を呼び出すと Normal ブロックが作成されます。 Client ブロックを使用せずに Normal ブロックだけを使用する場合は、_CRTDBG_MAP_ALLOC を定義することもできます。そうすると、デバッグ ビルドでは、すべてのヒープ割り当て関数の呼び出しが、対応するデバッグ バージョン関数の呼び出しに置き換えられます。 これによって、ヒープ割り当て関数の呼び出しに関連するファイル名と行番号情報を対応するブロック ヘッダーに格納できます。_CRT_BLOCK
多数のランタイム ライブラリ関数は、内部的にメモリ ブロックを割り当てます。このように内部的に割り当てられたメモリ ブロックは CRT ブロックとして個別に扱われます。 そのため、メモリ リークの検出などの処理には、これらのブロックは影響しません。 CRT 型のブロックが、割り当て関数によって割り当てられたり、再割り当てされたり、解放されたりすることはありません。_CLIENT_BLOCK
アプリケーションでは、デバッグ ヒープ関数を明示的に呼び出し、このメモリ ブロック型を割り当てることによって、特定の割り当て領域をデバッグの目的で特別に追跡できます。 たとえば、MFC はすべての CObjects を Client ブロックとして割り当てます。ほかのアプリケーションでも、さまざまなメモリ オブジェクトを Client ブロックとして保持している可能性があります。 より細かい追跡を実施するために、Client ブロック型を細分化することもできます。 Client ブロック型を細分化した型を指定するには、その型を表す数値を左に 16 ビットシフトし、_CLIENT_BLOCK との OR 演算を行います。 次に例を示します。#define MYSUBTYPE 4 freedbg(pbData, _CLIENT_BLOCK|(MYSUBTYPE<<16));
Client ブロックに格納されているオブジェクトをダンプするためにクライアント側で定義したフック関数を _CrtSetDumpClient を使用して組み込むこともできます。これにより、デバッグ関数が Client ブロックの内容をダンプするたびに、このフック関数が呼び出されるようになります。 また、_CrtDoForAllClientObjects を使用して、デバッグ ヒープ上の各 Client ブロックに対して、アプリケーション側で用意した特定の関数を呼び出すこともできます。
_FREE_BLOCK
通常は解放済みのブロックはリストから削除されます。 ただし、解放済みのメモリに書き込みが行われていないかどうかをチェックしたり、メモリ不足の状態をシミュレートしたりするために、解放されたブロックをリンク リストに残しておくこともできます。その場合は、解放されていることを示すために、既知のバイト値 (現在は 0xDD) が格納されます。_IGNORE_BLOCK
デバッグ ヒープ処理を一定期間だけオフにできます。 この間は、メモリ ブロックはリスト中に保持されますが、Ignore ブロックとしてマークされます。
特定のブロックの型や、その細分化された型を調べるには、_CrtReportBlockType 関数と、_BLOCK_TYPE マクロおよび _BLOCK_SUBTYPE マクロを使用します。 これらのマクロは、crtdbg.h で次のように定義されています。
#define _BLOCK_TYPE(block) (block & 0xFFFF)
#define _BLOCK_SUBTYPE(block) (block >> 16 & 0xFFFF)