_CrtSetDbgFlag

擷取或修改旗標的狀態 _crtDbgFlag ,以控制偵錯堆積管理員的配置行為(僅限偵錯版本)。

語法

int _CrtSetDbgFlag(
   int newFlag
);

參數

newFlag
的新狀態 _crtDbgFlag

傳回值

傳回 的先前狀態 _crtDbgFlag

備註

_CrtSetDbgFlag 式可讓應用程式透過修改旗標的 _crtDbgFlag 位欄位來控制偵錯堆積管理員如何追蹤記憶體配置。 藉由設定位欄位,應用程式可以指示偵錯堆積管理員執行特殊的偵錯作業。 有數個可能的作業:

  • 檢查應用程式結束時是否有記憶體流失,並報告是否有找到任何記憶體
  • 藉由指定釋放的記憶體區塊應該保留在堆積的連結清單中,以模擬低記憶體狀況,
  • 檢查每個配置要求的每個記憶體區塊,以確認堆積的完整性。

未定義 時 _DEBUG ,會在前置處理期間移除 對 的 _CrtSetDbgFlag 呼叫。

下表列出 的 _crtDbgFlag 位欄位,並描述其行為。 由於設定位會導致診斷輸出增加並降低程式執行速度,因此預設不會設定這些位(關閉)。 如需這些位欄位的詳細資訊,請參閱 堆積狀態報表函式

位元欄位 預設 描述
_CRTDBG_ALLOC_MEM_DF ON ON:啟用偵錯堆積配置,並使用記憶體區塊類型識別項,例如 _CLIENT_BLOCK。 OFF:將新的配置新增至堆積的連結清單,但將區塊類型設定為 _IGNORE_BLOCK

也可以與任何堆積頻率檢查巨集結合。
_CRTDBG_CHECK_ALWAYS_DF OFF ON:呼叫 _CrtCheckMemory 每個配置和解除配置要求。 OFF:必須明確地呼叫 _CrtCheckMemory

堆積頻率檢查巨集會在設定此旗標時沒有效果。
_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:不要在程式結束時自動執行洩漏檢查。

也可以與任何堆積頻率檢查巨集結合。

堆積檢查頻率巨集

您可以根據對 、 、 和 _msize 的呼叫 malloc 數目,指定 C 執行時間程式庫執行偵錯堆積驗證 _CrtCheckMemoryfree 的頻率。 realloc

然後 _CrtSetDbgFlag 會檢查 newFlag 參數的上層 16 位元以取得值。 指定的值是呼叫之間的 _CrtCheckMemoryreallocfree_msize 呼叫數目 malloc 。 針對此用途有四個預先定義的巨集。

Macro malloc呼叫之間的 、 reallocfree_msize 呼叫數目_CrtCheckMemory
_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 個 、 reallocfree_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);
}

指定 時 _CRTDBG_CHECK_ALWAYS_DF ,會忽略參數的上層 16 位 newFlag 。 在此情況下, _CrtCheckMemory 每次呼叫 、 reallocfree_msize 時,都會呼叫 malloc

newFlag 是要套用至 _crtDbgFlag 的新狀態,而且是每個位欄位的值組合。

變更一個或多個位元欄位並建立旗標的新狀態

  1. 呼叫 _CrtSetDbgFlag 等於 _CRTDBG_REPORT_FLAG 以取得目前 _crtDbgFlag 狀態,並將傳回的值儲存在暫 newFlag 存變數中。

  2. 使用對應的位元遮罩來開啟暫存變數的位 「or」 ( | ) 的任何位(以資訊清單常數表示于應用程式程式碼中)。

  3. 以適當位元遮罩的位 「not」 () 位 「not」 ( &~ ) 關閉變數的其他位。

  4. 呼叫 _CrtSetDbgFlag ,其 newFlag 等於儲存在暫存變數中的值,以設定 的新狀態 _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>

如需相容性詳細資訊,請參閱相容性

程式庫

僅限偵錯版本的 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 );
}

另請參閱

偵錯常式
_crtDbgFlag
_CrtCheckMemory