リソースの後処理

終了ハンドラーの実行中は、終了ハンドラーが呼び出される前に実際に取得されたリソースがわからない場合があります。 すべてのリソースが取得される前に __try ステートメント ブロックへの割り込みが発生したために、一部のリソースは開いていない可能性もあります。

安全のために、終了処理のクリーンアップに進む前に、どのリソースが開いているかをチェックする必要があります。 推奨される手順は、次のとおりです。

  1. 各ハンドルを NULL に初期化します。

  2. __try ステートメント ブロックで、各リソースを取得します。 ハンドルは、リソースが取得されると、正の値に設定されます。

  3. __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();
}

関連項目

終了ハンドラーの記述
Structured Exception Handling (C/C++)