リソースの後処理
終了ハンドラーの実行中は、終了ハンドラーが呼び出される前に実際に取得されたリソースがわからない場合があります。 すべてのリソースが取得される前に __try ステートメント ブロックへの割り込みが発生したために、一部のリソースは開いていない可能性もあります。
安全のために、終了処理のクリーンアップに進む前に、どのリソースが開いているかをチェックする必要があります。 推奨される手順は、次のとおりです。
各ハンドルを NULL に初期化します。
__tryステートメント ブロックで、各リソースを取得します。 ハンドルは、リソースが取得されると、正の値に設定されます。__finallyステートメント ブロックでは、対応するハンドルまたはフラグ変数がゼロ以外であるか、NULL でない、各リソースを解放します。
例
たとえば、次のコードでは、終了ハンドラーを使用して 3 つのファイルを閉じ、メモリ ブロックを解放します。 これらのリソースは、__try ステートメント ブロックで取得されました。 コードでは、リソースをクリーンアップする前に、まずリソースが取得されたかどうかを確認しています。
// exceptions_Cleaning_up_Resources.cpp
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <windows.h>
void fileOps() {
FILE *fp1 = NULL,
*fp2 = NULL,
*fp3 = NULL;
LPVOID lpvoid = NULL;
errno_t err;
__try {
lpvoid = malloc( BUFSIZ );
err = fopen_s(&fp1, "ADDRESS.DAT", "w+" );
err = fopen_s(&fp2, "NAMES.DAT", "w+" );
err = fopen_s(&fp3, "CARS.DAT", "w+" );
}
__finally {
if ( fp1 )
fclose( fp1 );
if ( fp2 )
fclose( fp2 );
if ( fp3 )
fclose( fp3 );
if ( lpvoid )
free( lpvoid );
}
}
int main() {
fileOps();
}