Share via


_CrtSetDbgFlag

更新 : 2007 年 11 月

_crtDbgFlag フラグの状態を取得または変更して、デバッグ ヒープ マネージャの動作を制御します (デバッグ バージョンだけ)。

int _CrtSetDbgFlag( 
   int newFlag 
);

パラメータ

  • newFlag
    _crtDbgFlag の新しい状態。

戻り値

_crtDbgFlag の前回の状態を返します。

解説

_CrtSetDbgFlag 関数を使用すると、アプリケーションは _crtDbgFlag フラグのビット フィールドを変更して、デバッグ ヒープ マネージャによるメモリ割り当ての追跡方法を制御できます。ビットを ON に設定すると、アプリケーションはデバッグ ヒープ マネージャに特殊なデバッグ操作の実行を命令できます。たとえば、アプリケーションの終了時にメモリ リークを確認する、メモリ リークの検出時にレポートする、解放したメモリ ブロックをヒープのリンク リストに保持してメモリ不足の状況をシミュレートする、割り当て要求のたびに各メモリ ブロックをチェックしてヒープの整合性を検査するなどの処理を実行できます。_DEBUG が未定義の場合、_CrtSetDbgFlag の呼び出しはプリプロセスで削除されます。

_crtDbgFlag のビット フィールドとその動作を次の表に一覧表示します。ビットを設定すると診断のための出力が増加してプログラムの実行速度が低下するため、既定ではこれらのビットは未設定 (OFF) になっています。ビット フィールドの詳細については、「デバッグ ヒープ」を参照してください。

ビット フィールド

既定の動作

説明

_CRTDBG_ALLOC_MEM_DF

ON

ON : デバッグ ヒープ割り当てと、_CLIENT_BLOCK などのメモリ ブロック型識別子の使用を有効にします。OFF : ヒープのリンク リストに新しい割り当てを追加しますが、ブロック型は _IGNORE_BLOCK に設定されます。

ヒープ頻度チェック マクロと組み合わせることもできます。

_CRTDBG_CHECK_ALWAYS_DF

OFF

ON : 割り当て要求および解放要求のたびに _CrtCheckMemory を呼び出します。OFF : _CrtCheckMemory を明示的に呼び出す必要があります。

このフラグを ON に設定すると、ヒープ頻度チェック マクロは無効となります。

_CRTDBG_CHECK_CRT_DF

OFF

ON : _CRT_BLOCK 型が、リーク検出およびメモリ状態の差分比較の対象になります。OFF : ランタイム ライブラリが内部的に使用するメモリは、リーク検出およびメモリ状態の差分比較の操作で無視されます。

ヒープ頻度チェック マクロと組み合わせることもできます。

_CRTDBG_DELAY_FREE_MEM_DF

OFF

ON : 解放したメモリ ブロックをヒープのリンク リストに保持し、_FREE_BLOCK 型を割り当て、バイト値 0xDD を設定します。OFF : 解放したブロックをヒープのリンク リストに保持しません。

ヒープ頻度チェック マクロと組み合わせることもできます。

_CRTDBG_LEAK_CHECK_DF

OFF

ON : プログラムの終了時に _CrtDumpMemoryLeaks を呼び出して、メモリ リークのチェックを自動的に実行します。アプリケーションが割り当てたメモリを完全に解放できない場合は、エラー レポートを生成します。OFF : プログラムの終了時にメモリ リークのチェックを自動的に実行しません。

ヒープ頻度チェック マクロと組み合わせることもできます。

ヒープ チェック頻度マクロ

C ランタイム ライブラリがデバッグ ヒープの検証 (_CrtCheckMemory) を実行する頻度を mallocreallocfree、および _msize の呼び出し回数に基づいて指定できます。

_CrtSetDbgFlag は、値のパラメータ newFlag の上位 16 ビットを検査します。指定された値は、_CrtCheckMemory の呼び出しの間に行われる mallocreallocfree、および _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 (既定ではヒープ チェックなし)

既定では、mallocreallocfree、および _msize を 1,024 回呼び出すごとに _CrtCheckMemory が 1 回呼び出されます。

たとえば、16 回の mallocreallocfree、および _msize の操作ごとに 1 回のヒープ チェックを指定するには、次のコードを使用します。

#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 freqency
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;

// Set the new bits
_CrtSetDbgFlag(tmp);
}

_CRTDBG_CHECK_ALWAYS_DF を指定すると、パラメータ newFlag の上位 16 ビットは無視されます。この場合、mallocreallocfree、および _msize が呼び出されるたびに _CrtCheckMemory が呼び出されます。

newFlag は、_crtDbgFlag に適用する新しい状態を示しており、各ビット フィールドの値の組み合わせです。

1 つ以上のビット フィールドを変更してフラグの新しい状態を作成する手順

  1. newFlag に _CRTDBG_REPORT_FLAG を設定して _CrtSetDbgFlag を呼び出し、_crtDbgFlag の現在の状態を取得して戻り値をテンポラリ変数に格納します。

  2. このテンポラリ変数と対応するビットマスク (アプリケーションでは記号定数で表現しています) の OR (論理和) をとり、ビットを ON に設定します。

  3. テンポラリ変数と、対応するビットマスクのビットごとの NOT との AND (論理積) をとり、残りのビットを OFF にします。

  4. テンポラリ変数に格納されている値を 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 );

メモリ管理とデバッグ ヒープの概要については、「メモリ管理とデバッグ ヒープ」を参照してください。

_CrtSetDbgFlag 関数でフラグを無効にするには、ビットマスクのビットごとの NOT と変数の AND をとる必要があります。

newFlag が有効な値ではない場合、「パラメータの検証」に説明されているように、この関数は無効なパラメータ ハンドラを呼び出します。実行の継続が許可された場合、この関数は errno を EINVAL に設定し、前の状態の _crtDbgFlag を返します。

必要条件

ルーチン

必須ヘッダー

_CrtSetDbgFlag

<crtdbg.h>

互換性の詳細については、「C ランタイム ライブラリ」の「互換性」を参照してください。

ライブラリ

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 );
}

.NET Framework の相当するアイテム

適用できません。標準 C 関数を呼び出すには、PInvoke を使用します。詳細については、「プラットフォーム呼び出しの例」を参照してください。

参照

概念

ヒープの状態をレポートする関数

参照

デバッグ ルーチン

_crtDbgFlag

_CrtCheckMemory