_CrtSetDbgFlag
检索或修改 _crtDbgFlag 该值指示控件调试堆管理器的分配行为 (请只调试版本)。
int _CrtSetDbgFlag(
int newFlag
);
参数
- newFlag
_crtDbgFlag的新状态。
返回值
返回 _crtDbgFlag以前的状态。
备注
_CrtSetDbgFlag 功能允许应用程序控制调试堆管理器如何通过修改 _crtDbgFlag 位标志的字段来跟踪内存分配。 通过设置位 (打开),应用程序可以提示调试堆管理器执行特殊调试操作,包括检查内存泄漏,当应用程序退出时,并报告,如果找到相应文件,以模拟内存不足情况通过指定已释放的堆中的存储区域应保持连接表,并且,验证堆的完整性通过检查每 store 区域根据每个分配请求。 当 _DEBUG 未定义时,在预处理期间,对 _CrtSetDbgFlag 中移除。
下表列出的 _crtDbgFlag 位域并描述它们的行为。 由于设置都会产生增加的诊断输出和降低程序执行速度,这些位未设置 (关闭) 默认情况下。 有关这些位域的更多信息,请参见 使用调试堆。
位域 |
默认 |
描述 |
---|---|---|
_CRTDBG_ALLOC_MEM_DF |
ON |
在:enable 调试堆到内存块类型的标识符赋值和使用,例如 _CLIENT_BLOCK。 :向堆中的新分配的链接表,但是,设置块类型为 _IGNORE_BLOCK。 还可以将与任何堆频率检查宏。 |
_CRTDBG_CHECK_ALWAYS_DF |
OFF |
在:调用 _CrtCheckMemory 根据每个分配和解除分配请求。 :必须显式调用 _CrtCheckMemory。 在此标志设置为时,堆频率检查宏不起作用。 |
_CRTDBG_CHECK_CRT_DF |
OFF |
在:包括 _CRT_BLOCK 输入泄漏检测和内存状态差异操作。 :运行库内部使用的内存由这些操作忽略。 还可以将与任何堆频率检查宏。 |
_CRTDBG_DELAY_FREE_MEM_DF |
OFF |
在:keep 堆上释放了存储区域连接表,它们分配 _FREE_BLOCK 类型,并用字节值 0xDD 填充它们。 :不要保留已释放块在堆的链接列表。 还可以将与任何堆频率检查宏。 |
_CRTDBG_LEAK_CHECK_DF |
OFF |
在:执行检查在程序的自动泄漏通过调用退出到 _CrtDumpMemoryLeaks 并生成错误报告,则分配的应用程序未能释放所有内存。 :不要自动执行检查在程序的泄漏退出。 还可以将与任何堆频率检查宏。 |
堆 CHECK 频率宏
可以指定 C 运行库的频率根据数字 (_CrtCheckMemory) 的验证调试堆调用 malloc、realloc、可用和 _msize。
_CrtSetDbgFlag 然后检查 newFlag 参数的上限 16 位值。 指定的值是 malloc,realloc,可用的数字,因此,_msize 调用 _CrtCheckMemory 之间调用。 因此提供四个预定义的宏。
宏 |
malloc 的数字,realloc,免,并_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 (默认情况下,不检查堆) |
默认情况下,在每 1,024 次调用 malloc、realloc、可用和 _msize,_CrtCheckMemory 调用。
例如,可以指定堆检查每 16 malloc、realloc、可用和 _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 freqency
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;
// Set the new bits
_CrtSetDbgFlag(tmp);
}
当_CRTDBG_CHECK_ALWAYS_DF 指定时,newFlag 参数的上限 16 位被忽略。 在这种情况下,每次调用 malloc、realloc、可用和 _msize,_CrtCheckMemory 调用。
newFlag 是应用的新状态于 _crtDbgFlag 和是值的组合每个的位域。
更改一个或多个位域并创建标志的新状态
调用 _CrtSetDbgFlag 和 newFlag 等于 _CRTDBG_REPORT_FLAG 获取当前 _crtDbgFlag 状态和存储返回值将在一个临时变量。
由 OR的所有位-运算置与对应的位屏蔽的临时变量 (在应用程序代码中由清单常数)。
由 AND按位关闭其他 BITS -运算与适当的位掩码 NOT 的变量。
调用 _CrtSetDbgFlag 和 newFlag 等于在临时变量中存储的值设置 _crtDbgFlag的新状态。
下面的代码堆上演示如何通过保留已释放的模拟内存不足情况 store 区域连接表并防止 _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 功能的标志,则按位应 AND 与该位掩码 NOT 的变量。
如果 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 );
}
.NET Framework 等效项
不适用。若要调用标准 C 函数,请使用 PInvoke。有关更多信息,请参见 平台调用示例。