CRT アサーション
このトピックの内容は、次の製品に該当します。
エディション |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
ネイティブのみ |
||||
Pro、Premium、Ultimate |
ネイティブのみ |
CRTDBG.H ヘッダー ファイルには、アサーションによるチェックを行うための _ASSERT マクロと _ASSERTE マクロが定義されています。
マクロ |
結果 |
---|---|
_ASSERT |
指定した式が FALSE と評価された場合、_ASSERT 対象のファイル名と行番号を出力します。 |
_ASSERTE |
_ASSERT と同様の結果と共に、アサートされた式の文字列形式も出力します。 |
FALSE と評価されたアサート対象の式もレポートするため、_ASSERTE マクロの方が強力です。 このマクロを使用すると、ソース コードを参照しなくても問題を識別できます。 ただし、アプリケーションのデバッグ バージョンに、_ASSERTE を使用してアサートした式ごとに文字列定数が含まれることになります。 _ASSERTE マクロを多用すると、これらの文字列式がかなりのメモリを占有します。 これが問題となる場合は、_ASSERT マクロを使用してメモリを節約してください。
_DEBUG が定義されている場合、_ASSERTE マクロは次のように定義されます。
#define _ASSERTE(expr) \
do { \
if (!(expr) && (1 == _CrtDbgReport( \
_CRT_ASSERT, __FILE__, __LINE__, #expr))) \
_CrtDbgBreak(); \
} while (0)
アサート対象の式が FALSE と評価された場合、_CrtDbgReport が呼び出され、アサーションが失敗したことをレポートします。既定では、メッセージ ダイアログ ボックスが表示されます。 このメッセージ ダイアログ ボックスで [再試行] をクリックすると、_CrtDbgReport は 1 を返し、_CrtDbgBreak は DebugBreak を使用してデバッガーを呼び出します。
printf の置換
_ASSERTE を使用して、次のコードを置換できます。
#ifdef _DEBUG
if ( someVar > MAX_SOMEVAR )
printf( "OVERFLOW! In NameOfThisFunc( ),
someVar=%d, otherVar=%d.\n",
someVar, otherVar );
#endif
上記のコードが、次の 1 ステートメントに置換されます。
_ASSERTE(someVar <= MAX_SOMEVAR);
ヒープ破損のチェック
次の例は、_CrtCheckMemory を使用してヒープの破損をチェックします。
_ASSERTE(_CrtCheckMemory());
ポインターの有効性チェック
次の例は、_CrtIsValidPointer を使用して、指定したメモリ範囲への読み書きが有効かどうかを検証します。
_ASSERTE(_CrtIsValidPointer( address, size, TRUE );
次の例は、_CrtIsValidHeapPointer を使用して、ポインターがローカル ヒープ上のメモリを指しているかどうかを検証します。ここでのローカル ヒープとは、C ランタイム ライブラリのこのインスタンスによって作成および管理されるヒープを指します。DLL はライブラリの独自のインスタンスを持っているため、アプリケーション ヒープの外部に独自のヒープを所有していることになります。 このアサーションは、null アドレスや範囲外のアドレスだけでなく、静的変数、スタック変数、その他の非ローカル メモリを指すポインターも検出します。
_ASSERTE(_CrtIsValidPointer( myData );
メモリ ブロックのチェック
次の例は、_CrtIsMemoryBlock を使用して、メモリ ブロックがローカル ヒープ上にあり、有効なブロック型を持つかどうかを検証します。
_ASSERTE(_CrtIsMemoryBlock (myData, size, &requestNumber, &filename, &linenumber));