Расширение MemDumperValidator из DCRT-библиотеки значительно облегчает отладку памяти. По умолчанию DCRT-библиотека выдает сообщения об утечках памяти и проверках корректности тех блоков памяти, в которых оба типа записей (с начала — underwrites или с конца блока — overwrites) не подвергались разрушению. Оба отчета могут быть очень полезны, но если отчет об утечках памяти выглядит так, как показано ниже, то довольно трудно точно определить, в памяти какого типа произошла утечка:
Detected memory leaks
Dumping objects ->
с:\vc\INCLUDE\crtdbg.h(552) : (596} normal block at Ox008CD5BO,
24 bytes long.
Data: < k w k > 90 6B 8C 00 BO DD 8C 00 00 00 80 77 90 6В 8С 00
Object dump complete.
Как говорилось ранее, средств проверки корректности памяти, заданных по умолчанию, может оказаться недостаточно. Для отлавливания некоторых специальных видов записей в память необходима более глубокая проверка корректности (иначе вы вообще не сможете перехватывать такие записи). Дополнительные проверки корректности и информация отчетов об утечках памяти, обеспечиваемые расширением MemDumperValidator, особенно полезны во время отладки. Чем больше информации получено во время отладки, тем меньше времени она занимает.
Расширение MemDumperValidator использует в своей работе идентификаторы блоков памяти DCRT-библиотеки, что позволяет ему ассоциировать тип блока со специфическим набором функций работы с памятью, которым что-то известно о содержимом соответствующего блока. Каждому блоку памяти, распределенному через библиотеку DCRT, назначается специальный идентификатор, как показано в табл. 15.3. Типы блоков являются параметрами следующих функций распределения памяти библиотеки DCRT: _nh_maiioc_ dbg (new), _malloc_dbg (malloc), _calloc_dbg (calloc) И _realloc_dbg (realloc).
Таблица 15.3. Идентификаторы блоков памяти
Идентификатор блока | Описание |
_NORMAL_BLOCK |
Вызов обычной функции распределения (new, malloc или calloc) создает нормальные блоки. Определение #define _CRTDBG_MAP_ALLOC приводит к тому, что все распределения кучи по умолчанию являются нормальными блоками и связывают с блоком памяти имя исходного файла и номер строки, содержащей вызов соответствующей функции распределения |
_CRT_BLOCK |
Блоки памяти, распределяемые многими функциями библиотеки времени выполнения, помечаются как CRT-блоки, поэтому они могут быть обработаны отдельно (иначе, чем блоки других типов). В частности, появляется возможность исключить такие блоки из процедур обнаружения утечек памяти и других операций проверок корректности. Ваше приложение никогда не должно распределять, перераспределять или освобождать блоки подобного типа |
CLIENT BLOCK |
Если нужно, чтобы приложение выполняло специальную трассировку блоков распределенной памяти, то можно вызывать особые отладочные функции распределения, передавая им в качестве параметра специальное значение CLIENT BLOCK VALUE (см. ниже вызов heap alloc dbg после директивы #define). Можно прослеживать подтипы клиентских блоков, помещая 1 6-разрядное значение в 16 верхних разрядов значения блока, как показано ниже: #define CLIENT_BLOCK_VALUE(x) \ (_CLIENT_BLOCK | (x«16) ) heap alloc dbg ( 10, CLIENT BLOCK VALUE ( OxA) , _ FILE _ , _ LINE _ ) ; Для дампов блоков памяти этого типа (т. е. памяти, зарегистрированной в форме клиентских блоков) приложение может обеспечить функцию-обработчик (через функцию CrtSetDumpClient). Функция-обработчик будет вызываться всякий раз, когда функции DCRT-библиотеки потребуется выполнить дамп клиент- |