オブジェクト ダンプの解釈
このトピックの内容は、次の製品に該当します。
エディション |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
ネイティブのみ |
||||
Pro、Premium、Ultimate |
ネイティブのみ |
次のオブジェクト ダンプを詳しく検討してください。
{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
このダンプを生成したプログラムでは、メモリが明示的に割り当てられているのは 2 か所だけ (1 つはスタック上、もう 1 つはヒープ上) です。
// 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 への 3 つのポインターをとり、これらの引数を使用して CString メンバー変数を初期化します。 メモリ ダンプ情報を調べてみると、CPerson オブジェクトと一緒に 3 つの非オブジェクト ブロック (non-object block) (3、4、5) が表示されています。 これらのブロックは CString メンバー変数の文字を格納しており、CPerson オブジェクトのデストラクターが呼び出されても削除されないことがわかります。
2 番目にメモリが割り当てられたブロックは CPerson オブジェクト自体です。 $51A4 はブロックのアドレスを表し、その後にオブジェクトの内容が表示されています。これらの情報は、DumpAllObjectsSince によって呼び出された CPerson::Dump が出力したものです。
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 から派生されていないオブジェクトに対する割り当て、または、C のプリミティブ型 (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;
}