デバッグ ヒープ マネージャーの割り当て動作を制御するために、 _crtDbgFlag フラグの状態を取得または変更します (デバッグ バージョンのみ)。
構文
int _CrtSetDbgFlag(
int newFlag
);
パラメーター
newFlag
_crtDbgFlag の新しい状態。
戻り値
_crtDbgFlagの前の状態を返します。
解説
_CrtSetDbgFlag関数を使用すると、_crtDbgFlag フラグのビット フィールドを変更して、デバッグ ヒープ マネージャーがメモリ割り当てを追跡する方法をアプリケーションで制御できます。 ビット フィールドを設定することで、アプリケーションはデバッグ ヒープ マネージャーに特別なデバッグ操作を実行するように指示できます。 いくつかの操作が考えられます。
- アプリケーションの終了時にメモリ リークをチェックし、見つかった場合は報告します。
- 解放されたメモリ ブロックをヒープのリンク リストに残す必要があることを指定して、メモリ不足状態をシミュレートする。
- 割り当て要求ごとに各メモリ ブロックを調べることで、ヒープの整合性を確認します。
_DEBUG が定義されていない場合、_CrtSetDbgFlag の呼び出しは前処理で削除されます。
次の表に、 _crtDbgFlag のビット フィールドとその動作を示します。 ビットを設定すると、診断出力が増加し、プログラムの実行速度が低下するため、これらのビットは既定では設定されていません (オフになっています)。 これらのビット フィールドの詳細については、「 Heap 状態レポート関数を参照してください。
| ビット フィールド | 既定値 | 説明 |
|---|---|---|
_CRTDBG_ALLOC_MEM_DF |
ON | オン: デバッグ ヒープ割り当てと、_CLIENT_BLOCK などのメモリ ブロック型識別子の使用を有効にします。 OFF: ヒープのリンク リストに新しい割り当てを追加しますが、ブロックの種類を _IGNORE_BLOCK に設定します。ヒープ頻度チェック マクロのいずれかと組み合わせることもできます。 |
_CRTDBG_CHECK_ALWAYS_DF |
OFF | ON: 割り当て要求と割り当て解除要求ごとに _CrtCheckMemory を呼び出します。 オフ: _CrtCheckMemory を明示的に呼び出す必要があります。このフラグが設定されている場合、ヒープ頻度チェック マクロは効果がありません。 |
_CRTDBG_CHECK_CRT_DF |
OFF | オン: リーク検出およびメモリ状態比較の操作に _CRT_BLOCK 型を含めます。 オフ: ランタイム ライブラリによって内部的に使用されるメモリは、これらの操作では無視されます。ヒープ頻度チェック マクロのいずれかと組み合わせることもできます。 |
_CRTDBG_DELAY_FREE_MEM_DF |
OFF | ON: 解放されたメモリ ブロックをヒープのリンク リストに保持し、 _FREE_BLOCK 型を割り当てて、バイト値0xDDで入力します。 オフ: 解放されたブロックをヒープのリンク リストに保持しません。ヒープ頻度チェック マクロのいずれかと組み合わせることもできます。 |
_CRTDBG_LEAK_CHECK_DF |
OFF | ON: _CrtDumpMemoryLeaks の呼び出しを介してプログラム終了時に自動リーク チェックを実行し、アプリケーションが割り当てられたすべてのメモリを解放できなかった場合にエラー レポートを生成します。 オフ: プログラムの終了時に自動的なリーク チェックを行いません。ヒープ頻度チェック マクロのいずれかと組み合わせることもできます。 |
ヒープ頻度チェック マクロ
C ランタイム ライブラリがデバッグ ヒープ (_CrtCheckMemory) の検証を実行する頻度を、malloc、realloc、free、_msize の呼び出しの数に基づいて指定できます。
_CrtSetDbgFlag は、newFlag パラメーターの上位 16 ビットで値を調べます。 指定された値は、_CrtCheckMemory の呼び出し間の malloc、realloc、free、_msize の呼び出し数です。 この目的のために、4 つの定義済みマクロが用意されています。
| マクロ | _CrtCheckMemory の呼び出し間の malloc、realloc、free、_msize の呼び出しの数 |
|---|---|
_CRTDBG_CHECK_EVERY_16_DF |
16 |
_CRTDBG_CHECK_EVERY_128_DF |
128 |
_CRTDBG_CHECK_EVERY_1024_DF |
1024 |
_CRTDBG_CHECK_DEFAULT_DF |
0 (既定では、ヒープ チェックなし) |
既定では、 _CrtCheckMemory はメモリ操作中に呼び出されません。 これは、上記のフラグを _CrtSetDbgFlag()に送信することで変更できます。
たとえば、次のコードを使用して、16 個の malloc、 realloc、 free、 _msize 操作ごとにヒープ チェックを指定できます。
#include <crtdbg.h>
int main( )
{
int tmp;
// Get the current bits
tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Clear the upper 16 bits and OR in the desired frequency
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;
// Set the new bits
_CrtSetDbgFlag(tmp);
}
newFlag パラメーターの上位 16 ビットは、_CRTDBG_CHECK_ALWAYS_DF が指定されている場合は無視されます。 この場合、malloc、realloc、free、_msize を呼び出すたびに _CrtCheckMemory が呼び出されます。
newFlag は、 _crtDbgFlag に適用する新しい状態であり、各ビット フィールドの値の組み合わせです。
これらのビット フィールドを変更して、フラグの新しい状態を作成するには
newFlagを_CRTDBG_REPORT_FLAGと同じにして_CrtSetDbgFlagを呼び出して現在の_crtDbgFlagの状態を取得し、返された値を一時変数に格納します。この一時変数と対応するビットマスクとの "OR" (
|) 演算を行い、ビットをオンにします。ビットマスクは、アプリケーション コードの中ではマニフェスト定数で表されます。一時変数と、適切なビットマスクのビットごとの "NOT" (
~) との "AND" (&) 演算を行い、他のビットをオフにします。newFlagを一時変数に格納されている値と同じにして_CrtSetDbgFlagを呼び出すことによって、_crtDbgFlagの新しい状態を設定します。
次のコードは、解放されたメモリ ブロックをヒープのリンク リストに保持することでメモリ不足の状態をシミュレートし、割り当て要求のたびに _CrtCheckMemory が呼び出されないようにする方法を示しています。
// Get the current state of the flag
// and store it in a temporary variable
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// Turn On (OR) - Keep freed memory blocks in the
// heap's linked list and mark them as freed
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
// Turn Off (AND) - prevent _CrtCheckMemory from
// being called at every allocation request
tmpFlag &= ~_CRTDBG_CHECK_ALWAYS_DF;
// Set the new state for the flag
_CrtSetDbgFlag( tmpFlag );
メモリ管理とデバッグ ヒープの概要については、「 CRT デバッグ ヒープの詳細を参照してください。
_CrtSetDbgFlag 関数でフラグを無効にするには、変数と、ビットマスクのビットごとの "NOT" (~) を "AND" (&) 演算する必要があります。
newFlagが有効な値でない場合、この関数は、「パラメーターの検証で説明されているように、無効なパラメーター ハンドラーを呼び出します。 実行の継続が許可された場合、この関数は errno を EINVAL に設定し、_crtDbgFlag の以前の状態を返します。
要件
| ルーチンによって返される値 | 必須ヘッダー |
|---|---|
_CrtSetDbgFlag |
<crtdbg.h> |
互換性の詳細については、「 Compatibility」を参照してください。
ライブラリ
C ランタイム ライブラリのデバッグ バージョンのみ。
例
// crt_crtsetdflag.c
// compile with: /c -D_DEBUG /MTd -Od -Zi -W3 /link -verbose:lib /debug
// This program concentrates on allocating and freeing memory
// blocks to test the functionality of the _crtDbgFlag flag.
#include <string.h>
#include <malloc.h>
#include <crtdbg.h>
int main( )
{
char *p1, *p2;
int tmpDbgFlag;
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
// Set the debug-heap flag to keep freed blocks in the
// heap's linked list - This will allow us to catch any
// inadvertent use of freed memory
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);
// Allocate 2 memory blocks and store a string in each
p1 = malloc( 34 );
p2 = malloc( 38 );
strcpy_s( p1, 34, "p1 points to a Normal allocation block" );
strcpy_s( p2, 38, "p2 points to a Client allocation block" );
// Free both memory blocks
free( p2 );
free( p1 );
// Set the debug-heap flag to no longer keep freed blocks in the
// heap's linked list and turn on Debug type allocations (CLIENT)
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
tmpDbgFlag &= ~_CRTDBG_DELAY_FREE_MEM_DF;
_CrtSetDbgFlag(tmpDbgFlag);
// Explicitly call _malloc_dbg to obtain the filename and
// line number of our allocation request and also so we can
// allocate CLIENT type blocks specifically for tracking
p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );
p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );
strcpy_s( p1, 40, "p1 points to a Normal allocation block" );
strcpy_s( p2, 40, "p2 points to a Client allocation block" );
// _free_dbg must be called to free the CLIENT block
_free_dbg( p2, _CLIENT_BLOCK );
free( p1 );
// Allocate p1 again and then exit - this will leave unfreed
// memory on the heap
p1 = malloc( 10 );
}