診断サービス
Microsoft Foundation Class ライブラりは、プログラムのデバッグをより簡単にする多くの診断サービスを提供します。 これらの診断サービスには、プログラムのメモリー割り当てを追跡したり、実行時にオブジェクトの内容をダンプしたり、実行時にデバッグ メッセージを表示したりできるようにするマクロやグローバル関数が含まれます。 診断サービスのマクロとグローバル関数は、次のカテゴリに分類されます。
汎用診断マクロ
汎用診断関数と変数
オブジェクト診断関数
これらのマクロと関数は、MFC のデバッグ バージョンとリリース バージョンの CObject
から派生するすべてのクラスで使用できます。 ただし、DEBUG_NEWと VERIFY を除くすべての機能は、リリース バージョンでは何も行いません。
デバッグ ライブラリでは、割り当てられたすべてのメモリ ブロックが一連の "ガード バイト" で角かっこで囲まれています。これらのバイトが誤ったメモリ書き込みによって妨げられると、診断ルーチンによって問題が報告される可能性があります。 行:
#define new DEBUG_NEW
実装ファイルでは、 new
のすべての呼び出しで、メモリ割り当てが行われたファイル名と行番号が格納されます。 関数 CMemoryState::DumpAllObjectsSince は、この追加情報を表示して、メモリ リークを識別できるようにします。 診断出力の追加情報については、クラス CDumpContext も参照してください。
さらに、C ランタイム ライブラリは、アプリケーションのデバッグに使用できる診断関数のセットもサポートしています。 詳細については、『ランタイム ライブラリ リファレンス』の「 デバッグ ルーチン 」を参照してください。
MFC 汎用診断マクロ
名前 | 説明 |
---|---|
ASSERT | ライブラリのデバッグ バージョンで、指定された式が FALSE に評価された場合、メッセージを出力し、プログラムを中止します。 |
ASSERT_KINDOF | オブジェクトが、指定されたクラスのオブジェクト、または指定されたクラスから派生したクラスのオブジェクトであることをテストします。 |
ASSERT_VALID | その AssertValid メンバー関数 (通常は CObject からオーバーライドされる) を呼び出すことにより、オブジェクトの内部の有効性をテストします。 |
DEBUG_NEW | デバッグ モードのすべてのオブジェクト割り当てにファイル名と行番号を指定します。これは、メモリー リークを見つけるのに役立ちます。 |
DEBUG_ONLY | ASSERT に類似していますが、式の値のテストは行いません。デバッグ モードでのみ実行されるコードで役立ちます。 |
ENSURE と ENSURE_VALID | データの正確性を検証するために使用します。 |
THIS_FILE | コンパイルするファイルの名前に展開します。 |
TRACE | ライブラリのデバッグ バージョンで printf に類似した機能を提供します。 |
VERIFY | ASSERT と類似していますが、ライブラリのリリース バージョンとデバッグ バージョンで式を評価します。 |
MFC 汎用診断関数と変数
名前 | 説明 |
---|---|
afxDump | デバッガー出力ウィンドウまたはデバッグ端末に CDumpContext 情報を送信するグローバル変数。 |
afxMemDF | デバッグ メモリ アロケーターの動作を制御するグローバル変数。 |
AfxCheckError | エラーかどうかを確認するため、そしてもしエラーであれば、適切なエラーをスローするために、渡される SCODE のテストに使用するグローバル変数。 |
AfxCheckMemory | 現在割り当てられているすべてのメモリの整合性を確認します。 |
AfxDebugBreak | 実行が中断されます。 |
AfxDump | デバッガーにある間に呼び出さると、デバッグ中にオブジェクトの状態をダンプします。 |
AfxDump | デバッグ中にオブジェクトの状態をダンプする内部関数。 |
AfxDumpStack | 現在のスタックのイメージを生成します。 この関数は、常に、静的にリンクされます。 |
AfxEnableMemoryLeakDump | メモリ リーク ダンプを有効にします。 |
AfxEnableMemoryTracking | メモリのトラッキングをオンまたはオフにします。 |
AfxIsMemoryBlock | メモリ ブロックが正しく割り当てられていることを確認します。 |
AfxIsValidAddress | メモリ アドレスの範囲がプログラムの境界内にあることを確認します。 |
AfxIsValidString | 文字列へのポインターが有効かどうかを判断します。 |
AfxSetAllocHook | 各メモリ割り振りでの関数の呼び出しを有効にします。 |
MFC オブジェクト診断関数
名前 | 説明 |
---|---|
AfxDoForAllClasses | ランタイム型チェックをサポートする CObject から派生したすべてのクラスで、指定された関数を実行します。 |
AfxDoForAllObjects | new で割り当てられたすべてのCObject 派生オブジェクトに対して、指定された関数を実行します。 |
MFC コンパイル マクロ
名前 | 説明 |
---|---|
_AFX_SECURE_NO_WARNINGS | 非推奨の MFC 関数を使用するためのコンパイラ警告を抑制します。 |
_AFX_SECURE_NO_WARNINGS
非推奨の MFC 関数を使用するためのコンパイラ警告を抑制します。
構文
_AFX_SECURE_NO_WARNINGS
例
このコード サンプルでは、 _AFX_SECURE_NO_WARNINGS
が定義されていない場合にコンパイラ警告が発生します。
// define this before including any afx files in *pch.h* (*stdafx.h* in Visual Studio 2017 and earlier)
#define _AFX_SECURE_NO_WARNINGS
// . . .
CRichEditCtrl* pRichEdit = new CRichEditCtrl;
pRichEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
CRect(10,10,100,200), pParentWnd, 1);
char sz[256];
pRichEdit->GetSelText(sz);
AfxDebugBreak
MFC アプリケーションのデバッグ バージョンの実行で中断 ( AfxDebugBreak
の呼び出しの場所) を発生させるために、この関数を呼び出します。
構文
void AfxDebugBreak( );
解説
AfxDebugBreak
は MFC アプリケーションのリリース バージョンには影響しないため、削除する必要があります。 この関数は、MFC アプリケーションでのみ使用する必要があります。 非 MFC アプリケーションで中断を引き起こすには、Win32 API バージョン ( DebugBreak
) を使用します。
要件
Header: afxver_.h
ASSERT
引数を評価します。
ASSERT(booleanExpression)
パラメーター
booleanExpression
0 以外または 0 に評価される式 (ポインター値を含む) を指定します。
解説
結果が 0 の場合、マクロは診断メッセージを出力し、プログラムを中止します。 条件が 0 以外の場合、何も行われません。
診断メッセージにフォームがあります
assertion failed in file <name> in line <num>
ここで、 name はソース ファイルの名前、 num はソース ファイルで失敗したアサーションの行番号です。
MFC のリリース バージョンでは、ASSERT は式を評価しないため、プログラムを中断しません。 環境に関係なく式を評価する必要がある場合は、ASSERT の代わりに VERIFY マクロを使用します。
Note
この関数は、MFC のデバッグ バージョンでのみ使用できます。
例
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(pcage != NULL);
ASSERT(pcage->IsKindOf(RUNTIME_CLASS(CAge)));
// Terminates program only if pcage is NOT a CAge*.
要件
ヘッダー: afx.h
ASSERT_KINDOF
このマクロは、指すオブジェクトが指定されたクラスのオブジェクトであるか、指定したクラスから派生したクラスのオブジェクトであることをアサートします。
ASSERT_KINDOF(classname, pobject)
パラメーター
classname
CObject
派生クラスの名前。
pobject
クラス オブジェクトへのポインター。
解説
pobject パラメーターはオブジェクトへのポインターである必要があり、const
できます。 参照先のオブジェクトとクラスは、実行時クラス情報 CObject
サポートする必要があります。 たとえば、 pDocument
が CMyDoc
クラスまたはその派生クラスのオブジェクトへのポインターであることを確認するために、次のようにコーディングできます。
ASSERT_KINDOF(CMyDoc, pDocument);
ASSERT_KINDOF
マクロの使用は、コーディングとまったく同じです。
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
この関数は、[DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic または DECLARE_SERIAL マクロで宣言されたクラスでのみ機能します。
Note
この関数は、MFC のデバッグ バージョンでのみ使用できます。
要件
ヘッダー: afx.h
ASSERT_VALID
オブジェクトの内部状態の有効性に関する前提をテストするために使用します。
ASSERT_VALID(pObject)
パラメーター
pObject
AssertValid
メンバー関数のオーバーライド バージョンを持つCObject
から派生したクラスのオブジェクトを指定します。
解説
ASSERT_VALIDは、引数として渡されたオブジェクトの AssertValid
メンバー関数を呼び出します。
MFC のリリース バージョンでは、ASSERT_VALIDは何も行いません。 デバッグ バージョンでは、ポインターを検証し、NULL をチェックし、オブジェクト独自の AssertValid
メンバー関数を呼び出します。 これらのテストのいずれかが失敗した場合、アラート メッセージは ASSERT と同じ方法で表示されます。
Note
この関数は、MFC のデバッグ バージョンでのみ使用できます。
詳細と例については、「 MFC アプリケーションのデブギング」を参照してください。
例
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
要件
ヘッダー: afx.h
DEBUG_NEW
メモリ リークの検出を支援します。
#define new DEBUG_NEW
解説
DEBUG_NEWは、通常は new
演算子を使用してヒープ 記憶域を割り当てるプログラムのすべての場所で使用できます。
デバッグ モード ( _DEBUG シンボルが定義されている場合) DEBUG_NEWは、割り当てる各オブジェクトのファイル名と行番号を追跡します。 次に、 CMemoryState::D umpAllObjectsSince メンバー関数を使用すると、DEBUG_NEWで割り当てられた各オブジェクトが、割り当てられたファイル名と行番号で表示されます。
DEBUG_NEWを使用するには、ソース ファイルに次のディレクティブを挿入します。
#define new DEBUG_NEW
このディレクティブを挿入すると、プリプロセッサは new
を使用する場所にDEBUG_NEWを挿入し、MFC は残りの処理を行います。 プログラムのリリース バージョンをコンパイルすると、DEBUG_NEWは単純な new
操作に解決され、ファイル名と行番号の情報は生成されません。
Note
MFC の以前のバージョン (4.1 以前) では、IMPLEMENT_DYNCREATEまたはIMPLEMENT_SERIALマクロを呼び出したすべてのステートメントの後に、 #define
ステートメントを配置する必要がありました。 これはもう必要ありません。
要件
ヘッダー: afx.h
DEBUG_ONLY
デバッグ モードでは ( _DEBUG シンボルが定義されている場合)、DEBUG_ONLYはその引数を評価します。
DEBUG_ONLY(expression)
解説
リリース ビルドでは、DEBUG_ONLYはその引数を評価しません。 これは、デバッグ ビルドでのみ実行する必要があるコードがある場合に便利です。
DEBUG_ONLY マクロは、#ifdef _DEBUG
と#endif
を使用して式を囲むのと同じです。
例
void ExampleFunc(char* p, int size, char fill)
{
char* q; // working copy of pointer
VERIFY(q = p); // copy buffer pointer and validate
ASSERT(size >= 100); // make sure buffer is at least 100 bytes
ASSERT(isalpha(fill)); // make sure fill character is alphabetic
// if fill character is invalid, substitute 'X' so we can continue
// debugging after the preceding ASSERT fails.
DEBUG_ONLY(fill = (isalpha(fill)) ? fill : 'X');
}
要件
ヘッダー: afx.h
ENSURE と ENSURE_VALID
データの正確性を検証するために使用します。
構文
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
パラメーター
booleanExpression
テストするブール式を指定します。
解説
これらのマクロの目的は、パラメーターの検証を改善するためです。 マクロを使用すると、コード内の不適切なパラメーターをさらに処理できなくなります。 ASSERT マクロとは異なり、ENSURE マクロはアサーションの生成に加えて例外をスローします。
マクロは、プロジェクト構成に従って 2 つの方法で動作します。 マクロは ASSERT を呼び出し、アサーションが失敗した場合は例外をスローします。 したがって、デバッグ構成 (つまり、_DEBUGが定義されている場合) では、マクロはアサーションと例外を生成しますが、Release 構成では、マクロは例外のみを生成します (ASSERT は Release 構成の式を評価しません)。
マクロ ENSURE_ARGは ENSURE マクロと同様に動作します。
ENSURE_VALIDは、ASSERT_VALID マクロを呼び出します (デバッグ ビルドでのみ有効です)。 さらに、ポインターが NULL の場合、ENSURE_VALIDは例外をスローします。 NULL テストは、デバッグ構成とリリース構成の両方で実行されます。
これらのテストのいずれかが失敗した場合は、ASSERT と同じ方法でアラート メッセージが表示されます。 マクロは、必要に応じて無効な引数例外をスローします。
要件
ヘッダー: afx.h
THIS_FILE
コンパイルするファイルの名前に展開します。
構文
THIS_FILE
解説
この情報は ASSERT マクロと VERIFY マクロによって使用されます。 アプリケーション ウィザードとコード ウィザードは、作成したソース コード ファイルにマクロを配置します。
例
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// __FILE__ is one of the six predefined ANSI C macros that the
// compiler recognizes.
要件
ヘッダー: afx.h
TRACE
指定した文字列を現在のアプリケーションのデバッガーに送信します。
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
解説
TRACE の説明については、 ATLTRACE2 を参照してください。 TRACE とATLTRACE2の動作は同じです。
MFC のデバッグ バージョンでは、このマクロは、指定した文字列を現在のアプリケーションのデバッガーに送信します。 リリース ビルドでは、このマクロは何もコンパイルされません (コードはまったく生成されません)。
詳細については、「
要件
ヘッダー: afx.h
VERIFY
MFC のデバッグ バージョンで、その引数を評価します。
VERIFY(booleanExpression)
パラメーター
booleanExpression
0 以外または 0 に評価される式 (ポインター値を含む) を指定します。
解説
結果が 0 の場合、マクロは診断メッセージを出力し、プログラムを停止します。 条件が 0 以外の場合、何も行われません。
診断メッセージにフォームがあります
assertion failed in file <name> in line <num>
ここで、 name はソース ファイルの名前、 num はソース ファイルで失敗したアサーションの行番号です。
MFC のリリース バージョンでは、VERIFY は式を評価しますが、プログラムの出力や中断は行いません。 たとえば、式が関数呼び出しの場合、呼び出しが行われます。
例
// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system.
// It _is_ possible that GetDC() may fail, but the out-of-memory
// condition that causes it isn't likely. For a test application,
// this use of VERIFY() is fine. For any production code, this
// usage is dubious.
// get the display device context
HDC hdc;
VERIFY((hdc = ::GetDC(hwnd)) != NULL);
// give the display context back
::ReleaseDC(hwnd, hdc);
要件
ヘッダー: afx.h
afxDump (MFC の CDumpContext)
アプリケーションで基本的なオブジェクト ダンプ機能を提供します。
CDumpContext afxDump;
解説
afxDump
は定義済みの CDumpContext オブジェクトであり、デバッガーの出力ウィンドウまたはデバッグ ターミナルに CDumpContext
情報を送信できます。 通常、CObject::Dump
のパラメーターとしてafxDump
を指定します。
Windows NT とすべてのバージョンの Windows では、 afxDump
出力は、アプリケーションをデバッグするときに Visual C++ の [出力-デバッグ] ウィンドウに送信されます。
この変数は、MFC のデバッグ バージョンでのみ定義されます。 afxDump
の詳細については、「
例
// example for afxDump
CPerson* pMyPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << _T("Dumping myPerson:\n");
pMyPerson->Dump(afxDump);
afxDump << _T("\n");
#endif
要件
ヘッダー: afx.h
AfxDump (内部)
デバッグ中にオブジェクトの状態をダンプするために MFC が使用する内部関数。
構文
void AfxDump(const CObject* pOb);
パラメーター
pOb
CObject
から派生したクラスのオブジェクトへのポインター。
解説
AfxDump
は、オブジェクトの Dump
メンバー関数を呼び出し、 afxDump
変数で指定された場所に情報を送信します。 AfxDump
は、MFC のデバッグ バージョンでのみ使用できます。
プログラム コードは AfxDump
を呼び出すのではなく、適切なオブジェクトの Dump
メンバー関数を呼び出す必要があります。
要件
ヘッダー: afx.h
afxMemDF
この変数はデバッガーまたはプログラムからアクセスでき、割り当て診断を調整できます。
int afxMemDF;
解説
afxMemDF
は、列挙 afxMemDF
で指定された次の値を持つことができます。
allocMemDF
デバッグ アロケーター (デバッグ ライブラリの既定の設定) を有効にします。delayFreeMemDF
メモリの解放を遅延します。 プログラムがメモリ ブロックを解放している間、アロケーターはそのメモリを基になるオペレーティング システムに返しません。 これにより、プログラムに最大メモリ負荷がかけられます。checkAlwaysMemDF
メモリが割り当てられたり解放されたりするたびに、AfxCheckMemory
呼び出しが行われます。 これにより、メモリの割り当てと割り当て解除が大幅に遅くなります。
例
afxMemDF = allocMemDF | checkAlwaysMemDF;
要件
ヘッダー: afx.h
AfxCheckError
この関数は、渡された SCODE をテストして、エラーかどうかを確認します。
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
解説
エラーの場合、関数は例外をスローします。 渡された SCODE がE_OUTOFMEMORYの場合、関数は AfxThrowMemoryExceptionAfxThrowMemoryException を呼び出して、CMemoryException をスローします。 それ以外の場合、AfxThrowOleException を呼び出すことによって、関数は COleException をスローします。
この関数を使用して、アプリケーション内の OLE 関数の呼び出しの戻り値を確認できます。 アプリケーションでこの関数を使用して戻り値をテストすることで、最小限のコードでエラー状態に適切に対応できます。
Note
この関数は、デバッグ ビルドと非デバッグ ビルドで同じ効果を持ちます。
例
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
要件
ヘッダー: afx.h
AfxCheckMemory
この関数は、空きメモリ プールを検証し、必要に応じてエラー メッセージを出力します。
BOOL AfxCheckMemory();
戻り値
メモリ エラーがない場合は 0 以外。それ以外の場合は 0。
解説
関数がメモリの破損を検出しなかった場合、何も出力されません。
ヒープに現在割り当てられているすべてのメモリ ブロックがチェックされます。これには、 new
によって割り当てられたものも含まれますが、 malloc 関数や GlobalAlloc
Windows 関数など、基になるメモリ アロケーターへの直接呼び出しによって割り当てられたメモリ ブロックは含まれません。 ブロックが破損していることが判明した場合は、デバッガー出力にメッセージが出力されます。
行を含める場合
#define new DEBUG_NEW
プログラムモジュールで、その後の AfxCheckMemory
の呼び出しは、メモリが割り当てられたファイル名と行番号を示します。
Note
モジュールにシリアル化可能なクラスの 1 つ以上の実装が含まれている場合は、最後の IMPLEMENT_SERIAL マクロ呼び出しの後に #define
行を配置する必要があります。
この関数は、MFC のデバッグ バージョンでのみ機能します。
例
CAge* pcage = new CAge(21); // CAge is derived from CObject.
Age* page = new Age(22); // Age is NOT derived from CObject.
*(((char*)pcage) - 1) = 99; // Corrupt preceding guard byte
*(((char*)page) - 1) = 99; // Corrupt preceding guard byte
AfxCheckMemory();
要件
ヘッダー: afx.h
AfxDump (MFC)
デバッグ中にオブジェクトの状態をダンプするには、デバッガーでこの関数を呼び出します。
void AfxDump(const CObject* pOb);
パラメーター
pOb
CObject
から派生したクラスのオブジェクトへのポインター。
解説
AfxDump
は、オブジェクトの Dump
メンバー関数を呼び出し、 afxDump
変数で指定された場所に情報を送信します。 AfxDump
は、MFC のデバッグ バージョンでのみ使用できます。
プログラム コードは AfxDump
を呼び出すのではなく、適切なオブジェクトの Dump
メンバー関数を呼び出す必要があります。
要件
ヘッダー: afx.h
AfxDumpStack
このグローバル関数を使用して、現在のスタックのイメージを生成できます。
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
パラメーター
dwTarget
ダンプ出力のターゲットを示します。 ビットごとの OR (|
) 演算子を使用して組み合わせることができる値は次のとおりです。
AFX_STACK_DUMP_TARGET_TRACE TRACE マクロを使用して出力を送信します。 TRACE マクロはデバッグ ビルドでのみ出力を生成します。リリース ビルドでは出力が生成されません。 また、TRACE はデバッガー以外の他のターゲットにリダイレクトできます。
AFX_STACK_DUMP_TARGET_DEFAULT ダンプ出力を既定のターゲットに送信します。 デバッグ ビルドの場合、出力は TRACE マクロに送信されます。 リリース ビルドでは、出力はクリップボードに出力されます。
AFX_STACK_DUMP_TARGET_CLIPBOARD出力をクリップボードにのみ送信します。 データは、CF_TEXT クリップボード形式を使用してプレーン テキストとしてクリップボードに配置されます。
AFX_STACK_DUMP_TARGET_BOTH出力をクリップボードと TRACE マクロに同時に送信します。
AFX_STACK_DUMP_TARGET_ODS Win32 関数
OutputDebugString()
を使用してデバッガーに出力を直接送信します。 このオプションでは、デバッガーがプロセスにアタッチされている場合、デバッグ ビルドとリリース ビルドの両方でデバッガー出力が生成されます。 AFX_STACK_DUMP_TARGET_ODSは常にデバッガーに到達し (アタッチされている場合)、リダイレクトできません。
解説
次の例は、MFC ダイアログ アプリケーションのボタン ハンドラーから AfxDumpStack
を呼び出して生成された出力の 1 行を反映しています。
=== begin AfxDumpStack output ===
00427D55: DUMP2\DEBUG\DUMP2.EXE! void AfxDumpStack(unsigned long) + 181 bytes
0040160B: DUMP2\DEBUG\DUMP2.EXE! void CDump2Dlg::OnClipboard(void) + 14 bytes
0044F884: DUMP2\DEBUG\DUMP2.EXE! int _AfxDispatchCmdMsg(class CCmdTarget *,
unsigned int,int,void ( CCmdTarget::*)(void),void *,unsigned int,struct
AFX_CMDHANDLE
0044FF7B: DUMP2\DEBUG\DUMP2.EXE! virtual int CCmdTarget::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 626 bytes
00450C71: DUMP2\DEBUG\DUMP2.EXE! virtual int CDialog::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 36 bytes
00455B27: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnCommand(unsigned
int,long) + 312 bytes
00454D3D: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnWndMsg(unsigned
int,unsigned int,long,long *) + 83 bytes
00454CC0: DUMP2\DEBUG\DUMP2.EXE! virtual long CWnd::WindowProc(unsigned
int,unsigned int,long) + 46 bytes
004528D9: DUMP2\DEBUG\DUMP2.EXE! long AfxCallWndProc(class CWnd *,struct
HWND__ *,unsigned int,unsigned int,long) + 237 bytes
00452D34: DUMP2\DEBUG\DUMP2.EXE! long AfxWndProc(struct HWND__ *,unsigned
int,unsigned int,long) + 129 bytes
BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes
BFF928E0: WINDOWS\SYSTEM\KERNEL32.DLL! UTUnRegister + 2492 bytes
=== end AfxDumpStack() output ===
上記の出力の各行は、最後の関数呼び出しのアドレス、関数呼び出しを含むモジュールの完全なパス名、および呼び出された関数プロトタイプを示しています。 スタックの関数呼び出しが関数の正確なアドレスで発生しない場合は、バイトのオフセットが表示されます。
たとえば、上の出力の最初の行を次の表に示します。
出力 | 説明 |
---|---|
00427D55: |
最後の関数呼び出しのリターン アドレス。 |
DUMP2\DEBUG\DUMP2.EXE! |
関数呼び出しを含むモジュールの完全なパス名。 |
void AfxDumpStack(unsigned long) |
呼び出された関数プロトタイプ。 |
+ 181 bytes |
関数プロトタイプのアドレス (この場合は void AfxDumpStack(unsigned long) ) から戻りアドレス (この場合は 00427D55 ) までのオフセット (バイト単位)。 |
AfxDumpStack
は、MFC ライブラリのデバッグ バージョンと非デバッグ バージョンで使用できます。ただし、実行可能ファイルが共有 DLL で MFC を使用している場合でも、関数は常に静的にリンクされます。 共有ライブラリの実装では、関数は MFCS42 にあります。LIB ライブラリ (およびそのバリアント)。
この関数を正常に使用するには:
ファイル IMAGEHLP.DLLはパス上にある必要があります。 この DLL がない場合は、関数にエラー メッセージが表示されます。 IMAGEHLP によって提供される関数セットについてはイメージ・ヘルプ・ライブラリーを参照してください。
スタック上にフレームがあるモジュールには、デバッグ情報が含まれている必要があります。 デバッグ情報が含まれていない場合でも、関数はスタック トレースを生成しますが、トレースの詳細は少なくなります。
要件
ヘッダー: afx.h
AfxEnableMemoryLeakDump
AFX_DEBUG_STATEデストラクターのメモリ リーク ダンプを有効または無効にします。
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
パラメーター
bDump
[in]TRUE は、メモリ リーク ダンプが有効になっていることを示します。FALSE は、メモリ リーク ダンプが無効になっていることを示します。
戻り値
このフラグの以前の値。
解説
アプリケーションが MFC ライブラリをアンロードしたときに、MFC ライブラリがメモリ リークを確認します。 この時点で、メモリ リークは Visual Studio の Debug ウィンドウを通じてユーザーに報告されます。
アプリケーションが MFC ライブラリの前に別のライブラリを読み込んだ場合、そのライブラリ内の一部のメモリ割り当てが誤ってメモリ リークとして報告されます。 誤ったメモリ リークが原因で、MFC ライブラリがそれらを報告したときに、アプリケーションがゆっくりと終了する可能性があります。 このような場合、 AfxEnableMemoryLeakDump
を使用してメモリ リーク ダンプを無効にします。
Note
この方法を使用してメモリ リーク ダンプをオフにすると、アプリケーションで有効なメモリ リークのレポートを受け取らなくなります。 この方法を使用するのは、メモリ リーク ダンプに誤ったメモリ リークが含まれているという確信がある場合のみにする必要があります。
要件
ヘッダー: afx.h
AfxEnableMemoryTracking
診断メモリの追跡は、通常、MFC のデバッグ バージョンで有効になります。
BOOL AfxEnableMemoryTracking(BOOL bTrack);
パラメーター
bTrack
この値を TRUE に設定すると、メモリ追跡が有効になります。FALSE を指定すると、オフになります。
戻り値
追跡を有効にするフラグの前の設定。
解説
この関数を使用して、ブロックが正しく割り当てられていることがわかっているコードのセクションの追跡を無効にします。
AfxEnableMemoryTracking
の詳細については、「
Note
この関数は、MFC のデバッグ バージョンでのみ機能します。
例
BOOL CMyWinApp::InitInstance()
{
#ifdef _DEBUG
// Disable tracking of memory for the scope of the InitInstance()
AfxEnableMemoryTracking(FALSE);
#endif // _DEBUG
// ...
#ifdef _DEBUG
// Re-enable tracking of memory
AfxEnableMemoryTracking(TRUE);
#endif // _DEBUG
return TRUE;
}
要件
ヘッダー: afx.h
AfxIsMemoryBlock
メモリ アドレスをテストして、 new
の診断バージョンによって割り当てられた現在アクティブなメモリ ブロックを表していることを確認します。
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
パラメーター
P
テストするメモリブロックを指します。
nBytes
メモリ ブロックの長さをバイト単位で格納します。
plRequestNumber
メモリ ブロックの割り当てシーケンス番号で入力される long
整数を指します。現在アクティブなメモリ ブロックを表さない場合は 0 を指します。
戻り値
メモリ ブロックが現在割り当てられ、長さが正しい場合は 0 以外。それ以外の場合は 0。
解説
また、指定したサイズが、元の割り当て済みサイズと照合されます。 関数が 0 以外の値を返す場合、割り当てシーケンス番号は plRequestNumber で返されます。 この数値は、他のすべての new
割り当てに対してブロックが割り当てられた順序を表します。
例
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
要件
ヘッダー: afx.h
AfxIsValidAddress
任意のメモリ アドレスをテストして、プログラムのメモリ空間内に完全に格納されていることを確認します。
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
パラメーター
lp
テストするメモリ アドレスをポイントします。
nBytes
テストするメモリのバイト数を格納します。
bReadWrite
メモリの読み取りと書き込みの両方 (TRUE) と読み取り (FALSE) のどちらを行うかを指定します。
戻り値
デバッグ ビルドでは、指定されたメモリ ブロックがプログラムのメモリ空間内に完全に含まれている場合は 0 以外。それ以外の場合は 0。
デバッグ以外のビルドでは、 lp が NULL でない場合は 0 以外、それ以外の場合は 0。
解説
アドレスは、 new
によって割り当てられたブロックに限定されません。
例
// Allocate a 5 character array, which should have a valid memory address.
char* arr = new char[5];
// Create a null pointer, which should be an invalid memory address.
char* null = (char*)0x0;
ASSERT(AfxIsValidAddress(arr, 5));
ASSERT(!AfxIsValidAddress(null, 5));
要件
ヘッダー: afx.h
AfxIsValidString
この関数を使用して、文字列へのポインターが有効かどうかを判断します。
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
パラメーター
lpsz
テストするポインター。
nLength
テストする文字列の長さをバイト単位で指定します。 値 -1 は、文字列が null で終了することを示します。
戻り値
デバッグ ビルドでは、指定したポインターが指定したサイズの文字列を指している場合は 0 以外。それ以外の場合は 0。
デバッグ以外のビルドでは、 lpsz が NULL でない場合は 0 以外、それ以外の場合は 0。
例
// Create a character string which should be valid.
char str[12] = "hello world";
// Create a null pointer, which should be an invalid string.
char* null = (char*)0x0;
ASSERT(AfxIsValidString(str, 12));
ASSERT(!AfxIsValidString(null, 5));
要件
ヘッダー: afx.h
AfxSetAllocHook
各メモリ ブロックが割り当てられる前に、指定した関数の呼び出しを有効にするフックを設定します。
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
パラメーター
pfnAllocHook
呼び出す関数の名前を指定します。 割り当て関数のプロトタイプについては、「解説」を参照してください。
戻り値
割り当てを許可する場合は 0 以外。それ以外の場合は 0。
解説
Microsoft Foundation クラス ライブラリのデバッグ メモリ アロケーターは、ユーザー定義のフック関数を呼び出して、ユーザーがメモリ割り当てを監視したり、割り当てが許可されるかどうかを制御したりできます。 割り当てフック関数は、次のようにプロトタイプ化されます。
BOOL AFXAPI AllocHook( size_t nSize
, BOOL bObject
, LONG lRequestNumber
);
nSize
提案されたメモリ割り当てのサイズ。
bObject
割り当てが CObject
派生オブジェクトの場合は TRUE、それ以外の場合は FALSE。
lRequestNumber
メモリ割り当てのシーケンス番号。
AFXAPI 呼び出し規則は、呼び出し先がスタックからパラメーターを削除する必要があることを意味します。
要件
ヘッダー: afx.h
AfxDoForAllClasses
アプリケーションのメモリ空間内のすべてのシリアル化可能な CObject
派生クラスに対して、指定された反復関数を呼び出します。
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
パラメーター
pfn
各クラスに対して呼び出される反復関数を指します。 関数引数は、 CRuntimeClass
オブジェクトへのポインターと、呼び出し元が関数に提供する追加データへの void ポインターです。
pContext
呼び出し元が反復関数に提供できる省略可能なデータを指します。 このパラメーターは、NULL でもかまいません。
解説
シリアル化可能な CObject
派生クラスは、DECLARE_SERIAL マクロを使用して派生したクラスです。 pContext内のAfxDoForAllClasses
に渡されるポインターは、呼び出されるたびに指定された反復関数に渡されます。
Note
この関数は、MFC のデバッグ バージョンでのみ機能します。
例
#ifdef _DEBUG
void DoForAllClasses(const CRuntimeClass* pClass, void* pContext)
{
ASSERT(pContext != NULL);
CString* pStr = (CString*)pContext;
*pStr += pClass->m_lpszClassName;
*pStr += _T("\n");
}
#endif
#ifdef _DEBUG
CString cStr;
AfxDoForAllClasses(DoForAllClasses, &cStr);
AfxMessageBox(cStr);
#endif
要件
ヘッダー: afx.h
AfxDoForAllObjects
new
で割り当てられたCObject
から派生したすべてのオブジェクトに対して、指定された反復関数を実行します。
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
パラメーター
pfn
各オブジェクトに対して実行する反復関数を指します。 関数引数は、 CObject
へのポインターと、呼び出し元が関数に提供する追加データへの void ポインターです。
pContext
呼び出し元が反復関数に提供できる省略可能なデータを指します。 このパラメーターは、NULL でもかまいません。
解説
スタック、グローバル、または埋め込みオブジェクトは列挙されません。 pContext 内のAfxDoForAllObjects
に渡されるポインターは、呼び出されるたびに指定された反復関数に渡されます。
Note
この関数は、MFC のデバッグ バージョンでのみ機能します。
例
#ifdef _DEBUG
void DoForAllObjects(CObject* pObject, void* pContext)
{
int* pnCount = (int*)pContext;
pObject->AssertValid();
if (pnCount != NULL)
(*pnCount)++;
}
#endif // _DEBUG
#ifdef _DEBUG
//AfxDoForAllObjects will call the function DoForAllObjects
//For each CObject-derived object that is allocated on the heap
int nCount = 0;
AfxDoForAllObjects(DoForAllObjects, &nCount);
TRACE("%d Objects Checked\n", nCount);
#endif