Итак, мы знаем, что можем воспользоваться отладочным классом CMemoryState и его функцией DumpAllObjectsSince, чтобы получить дампы памяти. Давайте посмотрим шаг за шагом, как будет изменяться наш дамп в зависимости от нашего класса. Создадим простой класс.
#include "stdafx.h" #include "afxwin.h" class CmyPerson { public: CmyPerson(); }; CmyPerson::CmyPerson() { } void main() { CmyPerson *p; p=new CmyPerson(); CMemoryState cm; afxDump << "------------\n"; cm.DumpAllObjectsSince(); afxDump << "------------\n"; }
Вот его дамп:
------------ Dumping objects -> {21} normal block at 0x00770D20, 1 bytes long. Data: < > CD {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Что мы видим ??? Есть объект в памяти. Это не очень удобно так как объект в памяти. Для того, чтобы в дампе можно было увидеть имя к нему нужно добавить информацию времени выполнения. Вот изменения кода.
...... class CmyPerson : public CObject { public: CmyPerson(); DECLARE_DINAMIC(CmyPerson); }; IMPLEMENT_DINAMIC(CmyPerson,CObject); ......
Теперь дамп такой:
------------ Dumping objects -> {21} client block at 0x00770D20, subtype 0, 4 bytes long. a CObject object at $00770D20, 4 bytes long {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Мы видим, что этот объект порожденный от CObject видите различие между просто памятью и памятью объекта. Давайте посмотрим какой будет дамп, если у объекта есть данные:
...... class CmyPerson : public CObject { public: CmyPerson(); DECLARE_DINAMIC(CmyPerson); private: CString s1; CString s2; }; IMPLEMENT_DINAMIC(CmyPerson,CObject); CmyPerson::CmyPerson() { s1="hello Dump"; s2="Step by Step Web Site"; } ...... ------------ Dumping objects -> strcore.cpp(118) : {23} normal block at 0x00770740, 34 bytes long. Data: < Step> 01 00 00 00 15 00 00 00 15 00 00 00 53 74 65 70 strcore.cpp(118) : {22} normal block at 0x00770790, 23 bytes long. Data: < hell> 01 00 00 00 0A 00 00 00 0A 00 00 00 68 65 6C 6C {21} client block at 0x00770D10, subtype 0, 12 bytes long. a CObject object at $00770D10, 12 bytes long {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Вы видите, что в дампе отражаются и данные, которые были тоже помещены в динамическую память вместе с объектом. В данном случае, так как статические по отношению к объекту вы можете не волноваться они удалятся вместе с объектом. Посмотрите вот этот код:
void main() { CmyPerson *p; p=new CmyPerson(); delete p; CMemoryState cm; afxDump << "------------\n"; cm.DumpAllObjectsSince(); afxDump << "------------\n"; } ------------ Dumping objects -> {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Если память внутри объекта будет выделяться динамически, то дамп даст нам возможность увидеть ошибки ее выделения.
...... CmyPerson::CmyPerson() { s1=new CString("hello Dump"); s2=new CString("Step by Step Web Site"); } void main() { CmyPerson *p; p=new CmyPerson(); delete p; CMemoryState cm; afxDump << "------------\n"; cm.DumpAllObjectsSince(); afxDump << "------------\n"; } ......
В дампе мы это увидим:
------------ Dumping objects -> strcore.cpp(118) : {25} normal block at 0x00770710, 34 bytes long. Data: < Step> 01 00 00 00 15 00 00 00 15 00 00 00 53 74 65 70 {24} normal block at 0x00770760, 4 bytes long. Data: < w > 1C 07 77 00 strcore.cpp(118) : {23} normal block at 0x00770790, 23 bytes long. Data: < hell> 01 00 00 00 0A 00 00 00 0A 00 00 00 68 65 6C 6C {22} normal block at 0x00770CE0, 4 bytes long. Data: < w > 9C 07 77 00 {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Мы видим, что память выделяется и не освобождается. Где же ее искать ??? Вот как изменится дамп при использовании DEBUG_NEW:
------------ Dumping objects -> strcore.cpp(118) : {25} normal block at 0x00770710, 34 bytes long. Data: < Step> 01 00 00 00 15 00 00 00 15 00 00 00 53 74 65 70 E:\PROJECT\TestObject\TestObject.cpp(25) : {24} normal block at 0x00770760, 4 bytes long. Data: < w > 1C 07 77 00 strcore.cpp(118) : {23} normal block at 0x00770790, 23 bytes long. Data: < hell> 01 00 00 00 0A 00 00 00 0A 00 00 00 68 65 6C 6C E:\PROJECT\TestObject\TestObject.cpp(24) : {22} normal block at 0x00770CE0, 4 bytes long. Data: < w > 9C 07 77 00 {19} client block at 0x00770DB0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00770DB0, 64 bytes long Object dump complete. ------------
Щелкните два раза на этой строчке и курсор установится в ту строку, где выделена память и не удалена.