Использование MemDumperValidator в приложениях C++
К счастью, для того чтобы MemDumperValidator заработал в приложениях C++, нужно выполнить относительно простую операцию — определить особый класс для работы с расширением MemDumperValidator. В объявлении этого класса нужно определить макрос DECLARE_MEMDEBUG с именем класса в качестве параметра. Этот макрос немного похож на макрос MFC, который расширяется в пары объявлений — для данных и методов. При просмотре листинга 15-1 можно найти определения трех встроенных функций — new, delete и new, содержащих информацию об имени исходного файла и номере строки соответствующего вызова. Если в вашем классе определен любой из этих операторов, то необходимо извлечь их код из соответствующих операторов расширения и поместить его в операторы вашего класса.
В файле реализации вашего С++класса нужно использовать макрос IMPLEMENT_MEMDEBUG (и снова с именем класса в качестве параметра), который определяет статическую переменную этого класса. Макросы DECLARE
_MEMDEBUG И IMPLEMENT_MEMDEBUG работают только в отладочных построениях, поэтому их не следует обрамлять директивами условной компиляции.
После определения обоих макросов (и правильного их размещения в исходном коде), необходимо реализовать два метода, которые будут выполнять фактический дамп и проверку корректности блоков памяти. Прототипы этих методов выглядят так:
static void ClassDumper ( const void * pData);
static void ClassValidator ( const void * pData,
const void * pContext);
Очевидно, что эти методы следует разместить между директивами условной компиляции, для того чтобы они не компилировались в выпускных построениях.
Параметр pData в обоих методах — это указатель на блок памяти с экземпляром (объектом) данного класса. Для получения работоспособного указателя следует выполнить явное приведение типа значения, хранящегося в pData (т. е. адреса объекта), к типу класса. Во всех операциях, связанных с выдачей дампов и проверкой корректности (памяти), значения параметра pData следует использовать только для чтения, иначе в код может быть введено множество ошибок, которые придется устранять.
Второй параметр метода ClassValidator - pContext — это указатель на контекст, который вы передаете в первый вызов функции ValidateAliBlocks. Подробнее об этой функции рассказано чуть ниже, в разделе "Глубокие проверки корректности" данной главы.
Приведу две рекомендации по реализации метода ClassDumper. Во-первых, для того чтобы вывод форматированного дампа выполнялся в том же месте, что и вывод остальной части DCRT-библиотеки, нужно использовать макросы _RPTn и _RFTFn. Во-вторых, вывод дампов нужно заканчивать комбинацией символов CR/LF (Carriage Return/Line Feed — Возврат Каретки/Перевод Строки), потому что макросы DCRT-библиотеки не выполняют никакого форматирования.
Установка функций вывода дампов и проверок корректности блоков памяти для классов языка C++ является почти тривиальной задачей. Как же обстоят дела с выполнением подобных операций для структур данных языка С? К сожалению, аналогичная обработка С-структур требует немного больше усилий со стороны программиста.