_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 執行時間連結庫執行偵錯堆積驗證_CrtCheckMemory
free
的頻率。 realloc
然後 _CrtSetDbgFlag
會檢查 newFlag
參數的上層 16 位元以取得值。 指定的值是呼叫之間的 _CrtCheckMemory
、realloc
、 free
和 _msize
呼叫數目malloc
。 針對此用途有四個預先定義的巨集。
Macro | malloc 呼叫之間的 、realloc 、 free 和 _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
個、 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);
}
指定 時_CRTDBG_CHECK_ALWAYS_DF
,會忽略參數的上層 16 位newFlag
。 在這裡情況下,_CrtCheckMemory
每次呼叫、realloc
、 free
與_msize
時,都會呼叫 malloc
。
newFlag
是要套用至 _crtDbgFlag
的新狀態,而且是每個位字段的值組合。
變更一個或多個位元欄位並建立旗標的新狀態
呼叫
_CrtSetDbgFlag
等於_CRTDBG_REPORT_FLAG
以取得目前_crtDbgFlag
狀態,並將傳回的值儲存在暫newFlag
存變數中。使用對應的位掩碼來開啟暫存變數的位元 「or」 (
|
) 的任何位(以指令清單常數表示於應用程式程式代碼中)。以適當位掩碼的位 「not」 () 位元 「not」 (
&
~
) 關閉變數的其他位。呼叫
_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 );
}