Первым шагом к применению DCRT-библиотеки является включение ее в проект, что позволяет немедленно начать извлекать выгоду из мониторинга памяти. Для этого перед директивами #inciude главного файла проекта (или любого другого файла вашего проекта) необходимо добавить следующую строку:
#define _CRTDBG_MAP_ALLOC
Потом к имеющимся в программе заголовочным файлам следует добавить файл CRTDBG.H. Определение _CRTDBG_MAP_ALLOC будет переадресовывать обращения к обычным функциям распределения и освобождения памяти к специальным версиям этих функций, которые будут записывать в отчет имя и номер строки исходного файла каждой операции распределения или освобождения памяти.
Затем необходимо включить являющийся частью DCRT-библиотеки код управления кучей. Как говорилось в начале этой главы, большинство свойств DCRT-библиотеки по умолчанию выключено. Документация утверждает, что это сделано для того, чтобы сохранять небольшой размер кода и увеличивать скорость его выполнения. Хотя размер и скорость могут быть важны для сборки релиза (release build, выпускного построения), основной целью отладочного построения (debug build) является поиск ошибок! При отладке увеличенный размер и уменьшенная скорость выполнения приложения не имеют особого значения. Поэтому без колебаний включайте все свойства, которые, по вашему мнению, могут оказаться полезными. Функция _CrtsetDbgFiag принимает набор флагов, перечисленных в табл. 15.2. Чтобы включать различные режимы библиотеки DCRT, их можно объединять друг с другом операцией ок.
После сборки приложения с указанными выше директивами #inciude и #define и вызова функции _crtsetDbgFlag обеспечен полный доступ к библиотеке DCRT, многочисленные функции которой помогут управлять использованием памяти и получать соответствующие отчеты. Эти функции можно вызывать в любой точке приложения, а многие из них использовать внутри утверждений, что позволяет отлавливать проблемы памяти вблизи источника.
Одна из наиболее полезных функций DCRT — _CrtcheckMemory.
Она просматривает всю распределенную память и проверяет, не записывались ли какие-нибудь данные в начало или в конец блока, а также не перераспределялись ли предварительно освобожденные блоки памяти. Только из-за одной этой функции применение библиотеки DCRT оправдано!
Другой набор функций позволяет проверять корректность данных любой области памяти. Функции _CrtIsValidHeapPointer, _CrtIsMemoryBlock И _crtisVaiidPointer удобно использовать в качестве отладочных параметров функций проверки корректности. Вместе с _crtcheckMemory эти функции являются превосходными средствами проверки памяти.
Таблица 15.2. Флажки библиотеки DCRT
|
Флажок
|
Описание
|
|
_CRTDBG_ALLOC_MEM_DF |
Включает процесс распределения отладочной кучи и использования идентификаторов блоков памяти. Это единственный флажок, который включен по умолчанию |
|
_CRTDBG_CHECK_ALWAYS_DF |
Контролирует и проверяет корректность всей памяти при каждом запросе на распределение и освобождение (памяти). Включение этого флажка отлавливает записи и перезаписи сразу же, как только они происходят |
|
_CRTDBG_CHECK_CRT_DF |
Включает распределение памяти для функций библиотеки CRT во все процедуры обнаружения утечек памяти и расхождений состояния. При отсутствии проблем с функциями библиотеки CRT не устанавливайте этот флажок, в противном случае вы будете получать сообщения о распределении памяти для CRT-библиотеки. Поскольку последняя должна сохранять некоторую память распределенной до момента действительного завершения программы, которое происходит уже после формирования отчетов об утечках памяти, то большинство сообщений об утечках памяти будут ложными |
|
CRTDBG_DELAY_FREE_MEM_DF |
Вместо действительного освобождения памяти сохранять распределенные блоки во внутреннем списке кучи. Блоки заполняются значениями OxDD, поэтому, просматривая этот список в отладчике, можно получить информацию об освобождении памяти. Этот флажок позволяет тестировать |
|
(прод.) |
программу с предельными требованиями к памяти, без реального ее освобождения. Кроме того, по заполненности списка значениями OxDD библиотека DCRT будет проверять, не пытались ли вы снова получить доступ к освобожденному блоку памяти. Нужно всегда включать этот флажок, но имейте в виду, что при этом требования вашей программы к памяти легко могут удвоиться, потому что освобожденная память не восстанавливается за счет кучи |
|
_CRTDBG_LEAK_CHECK_DF |
Проверять утечки памяти в конце программы. Включение этого чрезвычайно полезного флажка обязательно |