Поделиться через


Интерпретация дампа объекта

Обновлен: Ноябрь 2007

Этот раздел применим к:

Выпуск

Visual Basic

C#

C++

Web Developer

Экспресс-выпуск

Тема не применяется Тема не применяется

Только машинные коды

Тема не применяется

Standard

Тема не применяется Тема не применяется

Только машинные коды

Тема не применяется

Pro и Team

Тема не применяется Тема не применяется

Только машинные коды

Тема не применяется

Обозначения:

Тема применяется

Применяется

Тема не применяется

Неприменимо

Тема применяется, но команда по умолчанию сокрыта

Команда или команды скрытые по умолчанию.

Рассмотрим этот дамп объекта более подробно:

{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4

Last Name: Smith
First Name: Alan
Phone #: 581-0215

{1} strcore.cpp(80) : non-object block at $00A7516E, 25 bytes long

Программа, которая создала этот дамп, выделяла память явным образом только дважды — один раз в стеке, а другой раз в куче:

// Do your memory allocations and deallocations.
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );

CPerson получает три аргумента — указатели на тип char, используемые для инициализации переменных-членов CString. В дампе памяти можно увидеть объект CPerson с тремя блоками без объектов (3, 4 и 5). В них хранятся знаки для переменных-членов CString и они не будут удалены при вызове деструктора объекта CPerson.

Блок номер 2 — это собственно объект CPerson. $51A4 представляет собой адрес блока, за которым следует содержимое объектов, выводимых CPerson::Dump при вызове DumpAllObjectsSince.

Нетрудно догадаться, что блок номер 1 связан с переменной фрейма CString, это видно из порядкового номера и размера, соответствующего количеству знаков в переменной фрейма CString. Переменные, размещенные во фрейме, автоматически освобождаются, когда фрейм выходит за пределы области действия.

Переменные фрейма

В основном можно не волноваться по поводу объектов кучи, связанных с переменными фрейма, потому что они автоматически освобождаются, когда эти переменные выходят за пределы области действия. Чтобы избежать беспорядка в диагностическом дампе, следует располагать вызовы Checkpointтак, чтобы они находились вне области действия переменных фрейма. Например, поместите фигурные скобки так, чтобы они окружали код предыдущего выделения памяти:

oldMemState.Checkpoint();
{
    // Do your memory allocations and deallocations ...
    CString s("This is a frame variable");
    // The next object is a heap object.
    CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
}
newMemState.Checkpoint();

С квадратными скобками в этих местах дамп памяти для этого примера выглядит следующим образом:

Dumping objects ->

{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4

Last Name: Smith
First Name: Alan
Phone #: 581-0215

Не-объектные выделения

Заметьте, что есть выделения-объекты (например, CPerson) и есть не-объекты. "Не-объектные выделения" — это выделения для объектов, которые не являются производными от CObject или выделения простых типов языка С, таких как char, int, или long. Если класс, производный от CObject, выделяет дополнительное пространство, например внутренний буфер, такие объекты отобразят и объектное, и не-объектное выделение.

Предотвращение утечек памяти

Заметьте: в приведенном выше коде блок памяти, связанный с переменной фрейма CString, был освобожден автоматически и не отобразился как утечка. Автоматическое освобождение, обусловленное правилами ограничения области видимости, предотвращает большинство утечек памяти, связанных с переменными фрейма.

Однако для объектов, распределенных в куче, во избежание утечки памяти нужно явно удалять объект. Чтобы очистить последнюю утечку памяти в предыдущем примере, удалите объект CPerson, распределенный в куче:

{
    // Do your memory allocations and deallocations.
    CString s("This is a frame variable");
    // The next object is a heap object.
    CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
    delete p;
}

См. также

Основные понятия

Дампы объектов

Ссылки

_CrtMemDumpAllObjectsSince

Другие ресурсы

Обнаружение утечек памяти в MFC