_CrtSetDbgFlag函数简介
(2017-04-07 10:07:44)分类: C/Cplusplus |
若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅
检索或修改的状态_crtDbgFlag标志来控制调试堆管理器 (仅限调试版本) 的分配行为。
int _CrtSetDbgFlag(
int newFlag
);
参数
newFlag
新状态的_crtDbgFlag。
返回的前一状态_crtDbgFlag。
_CrtSetDbgFlag
函数允许应用程序来控制调试堆管理器通过修改的位域跟踪内存分配的方式_crtDbgFlag标志。
通过设置位(打开),该应用程序可指示调试堆管理器执行特殊的调试操作,包括在应用程序退出时检查内存泄露并报告是否找到任何内存泄露、通过指定已释放的内存块应保留在堆的链接列表中来模拟内存不足情况,以及通过在每次分配请求时检查每个内存块来验证该堆的完整性。
当 _CrtSetDbgFlag
在预处理过程中删除。
下表列出的位域_crtDbgFlag并说明它们的行为。
因为设置位将导致诊断输出增加、程序执行速度减慢,因此在默认情况下不会设置这些位(已关闭)。
有关详细信息,有关这些位域,请参阅
位域 | 默认 | 描述 |
---|---|---|
_CRTDBG_ALLOC_MEM_DF | 打开 |
打开:启用调试堆分配并使用内存块类型标识符,例如 _CLIENT_BLOCK 。
关闭︰ 将新的分配添加到堆的链接列表,但设置阻止类型设置为_IGNORE_BLOCK。还可以与任何堆频率检查宏组合。 |
_CRTDBG_CHECK_ALWAYS_DF | 关闭 |
打开︰ 调用 _CrtCheckMemory 。设置此标志后,堆频率检查宏不会产生任何影响。 |
_CRTDBG_CHECK_CRT_DF |
关闭 |
打开:包括泄漏检测和内存状态差异操作中的 _CRT_BLOCK 还可以与任何堆频率检查宏组合。 |
_CRTDBG_DELAY_FREE_MEM_DF | 关闭 |
打开︰ 将已释放的内存块在堆链接列表中,将它们分配_FREE_BLOCK键入,然后使用字节值
0xDD 填充它们。 关闭:不要将已释放的块保留在堆链接列表中。 还可以与任何堆频率检查宏组合。 |
_CRTDBG_LEAK_CHECK_DF |
关闭 |
打开︰ 执行自动泄露检查在程序退出时通过调用 还可以与任何堆频率检查宏组合。 |
堆频率检查宏
您可以指定何种频率 C 运行库执行的调试堆的验证 (_CrtCheckMemory
)
基于对的调用次数malloc
, realloc
,免费,和_msize
。
然后,_CrtSetDbgFlag
newFlag
malloc
, realloc
,免费,和_msize
调用之间_CrtCheckMemory
调用。
为此,将提供四个预定义的宏。
宏 | 对 _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
将调用一次调用的每个
1024 次malloc
, realloc
,免费,和_msize
。
例如,可以指定 1 次堆检查每个 16 malloc
, realloc
,免费,和_msize
操作替换为以下代码︰
#include
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
_CrtCheckMemory
称为您每次调用malloc
, realloc
,免费,和_msize
。
newFlag
是要应用于的新状态_crtDbgFlag也是每位域的值的组合。
更改一个或多个位域并创建标志的新状态
-
调用
_CrtSetDbgFlag
与newFlag
等于_CRTDBG_REPORT_FLAG
以获取当前_crtDbgFlag状态,并在临时变量中存储返回的值。 -
通过对带有相应位掩码的临时变量(在应用程序代码中由清单常量显示)进行
OR
运算来打开任何位。 -
请关闭其他位由AND运算结果的变量进行按位不相应位掩码。
-
调用
_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 );
有关内存管理和调试堆的概述,请参阅
若要禁用有标志_CrtSetDbgFlag
函数,您应该AND的变量进行的按位不的位掩码。
如果newFlag
不是有效的值,此函数将调用无效参数处理程序,如中所述 errno
EINVAL
_crtDbgFlag
例程 | 必需的标头 |
---|---|
_CrtSetDbgFlag |
有关更多兼容性信息,请参阅“简介”中的
调试版本
// crt_crtsetdflag.c
// compile with: /c -D_DEBUG /MTd -Od -Zi -W3 /link -verbose:lib /debug
#include
#include
#include
int main( )
{
char *p1, *p2;
int tmpDbgFlag;
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);
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( p2 );
free( p1 );
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
tmpDbgFlag &= ~_CRTDBG_DELAY_FREE_MEM_DF;
_CrtSetDbgFlag(tmpDbgFlag);
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( p2, _CLIENT_BLOCK );
free( p1 );
p1 = malloc( 10 );
}