_CrtSetDbgFlag
Извлекает или изменяет состояние флага _crtDbgFlag
для управления поведением выделения диспетчера отладочной кучи (только отладочная версия).
Синтаксис
int _CrtSetDbgFlag(
int newFlag
);
Параметры
newFlag
Новое состояние для _crtDbgFlag
.
Возвращаемое значение
Возвращает предыдущее состояние _crtDbgFlag
.
Замечания
Функция _CrtSetDbgFlag
позволяет приложению управлять тем, как отладочный диспетчер куч отслеживает выделение памяти, изменив битовые поля флага _crtDbgFlag
. Задав битовые поля, приложение может указать диспетчеру кучи отладки выполнять специальные операции отладки. Существует несколько возможных операций:
- Проверка утечки памяти при выходе приложения из приложения и отправке отчетов, если они найдены,
- Имитация условий низкой памяти путем указания того, что освобожденные блоки памяти должны оставаться в связанном списке кучи.
- Проверка целостности кучи путем проверки каждого блока памяти при каждом запросе выделения.
Если _DEBUG
это не определено, вызовы _CrtSetDbgFlag
удаляются во время предварительной обработки.
В следующей таблице перечислены битовые поля для _crtDbgFlag
их поведения. Так как настройка битов приводит к увеличению выходных данных диагностики и снижению скорости выполнения программы, эти биты не задаются (отключены) по умолчанию. Дополнительные сведения об этих битовом полях см. в разделе "Функции отчетов о состоянии кучи".
Битовое поле | По умолчанию. | Description |
---|---|---|
_CRTDBG_ALLOC_MEM_DF |
DNS | ON: включение выделения памяти отладочной кучи и использование идентификаторов типов блоков памяти, таких как _CLIENT_BLOCK . OFF: добавьте новые выделения в связанный список кучи, но задайте для типа _IGNORE_BLOCK блока значение .Может также быть совмещено с любыми макросами частоты проверки кучи. |
_CRTDBG_CHECK_ALWAYS_DF |
ВЫКЛ. | ON: Вызов _CrtCheckMemory по каждому запросу на выделение и размещение сделки. OFF: _CrtCheckMemory необходимо вызывать явно.Макросы частоты проверки кучи не действуют, если задан этот флаг. |
_CRTDBG_CHECK_CRT_DF |
ВЫКЛ. | ON: включение типов _CRT_BLOCK в операции обнаружения утечек и разницы состояния памяти. OFF: память, используемая внутренне библиотекой времени выполнения, игнорируется этими операциями.Может также быть совмещено с любыми макросами частоты проверки кучи. |
_CRTDBG_DELAY_FREE_MEM_DF |
ВЫКЛ. | ON: сохраняйте свободные блоки памяти в связанном списке кучи, назначьте им _FREE_BLOCK тип и заполните их значением байтов 0xDD. OFF: не сохраняйте освобожденные блоки в связанном списке кучи.Может также быть совмещено с любыми макросами частоты проверки кучи. |
_CRTDBG_LEAK_CHECK_DF |
ВЫКЛ. | ON: выполните автоматическую проверку утечки при выходе программы через вызов _CrtDumpMemoryLeaks и создайте отчет об ошибке, если приложению не удалось освободить всю выделенную память. OFF: не выполняйте автоматическую проверку утечки при выходе программы.Может также быть совмещено с любыми макросами частоты проверки кучи. |
Макросы частоты проверки кучи
Вы можете указать, как часто библиотека времени выполнения C выполняет проверку отладочной кучи (_CrtCheckMemory
) на основе количества вызовов malloc
, realloc
free
и _msize
.
Затем _CrtSetDbgFlag
проверяет верхние 16 бит параметра newFlag
, чтобы получить значение. Указанное значение — число malloc
realloc
вызовов , free
и _msize
вызовы между _CrtCheckMemory
вызовами. Для этой цели предоставляется четыре готовых макроса.
Макрос | malloc Количество вызовов и free 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 (по умолчанию проверки кучи не выполняются) |
По умолчанию не вызывается во время операций с памятью _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);
}
При указании верхние 16 бит newFlag
параметра игнорируются _CRTDBG_CHECK_ALWAYS_DF
. В этом случае _CrtCheckMemory
вызывается каждый раз при вызове malloc
, realloc
free
и _msize
.
newFlag
— это новое состояние для применения к и _crtDbgFlag
является сочетанием значений для каждого битового поля.
Изменение одного или более битовых полей и создание нового состояния флага
Вызов
_CrtSetDbgFlag
сnewFlag
равным для_CRTDBG_REPORT_FLAG
получения текущего_crtDbgFlag
состояния и хранения возвращаемого значения во временной переменной.Включите все биты по битовой "или" (
|
) временной переменной с соответствующими битовыми масками (представленными в коде приложения константами манифеста).Отключите другие биты с побитовой "и" (
&
) переменной с побитовой "не" (~
) из соответствующих битовых кубков.Вызов
_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
функцией, используйте побитовое значение "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 );
}