バグ : 一時ファイルの作成

Posted: 2012年08月12日

一時ファイルを作成する際によく書いてしまうバグを紹介します。

プログラムプログラム:

 #include  <stdio.h>
 #include  <Windows.h>

 int main(int argc, char *argv[])
 {
    // GetTempPath APIでテンポラリファイル用のディレクトリパスを取得
    char lpszTempPath[MAX_PATH];
    if( ::GetTempPath(MAX_PATH, lpszTempPath) == 0 ) {
        return -1;
    }

    // 一時ファイルの作成
    char lpszTempFileName[MAX_PATH];
    if( ::GetTempFileName(lpszTempPath, "tmp", 1, lpszTempFileName) == 0 ) {
        return -1;
    }

    // 処理

    // 一時ファイルの削除
    ::DeleteFile(lpszTempFileName);

    return 0;
 }

このプログラムにどのような一時ファイル操作関連のバグがあると思いますか?

  • APIの仕様では、GetTempFileName関数の第3引数に0以外を指定した場合は、
    ファイルが作成されない。(※通常は作成される)
  • 処理でエラーになった場合は、一時ファイルの削除が考慮されていない

改善版プログラム改善版プログラム:

 #include  <stdio.h>
 #include  <Windows.h>
 #include <fstream>

 int main(int argc, char *argv[])
 {
    // GetTempPath APIでテンポラリファイル用のディレクトリパスを取得
    char lpszTempPath[MAX_PATH];
    if( ::GetTempPath(MAX_PATH, lpszTempPath) == 0 ) {
        return -1;
    }

    // 一時ファイルの作成
    char lpszTempFileName[MAX_PATH];
    if( ::GetTempFileName(lpszTempPath, "tmp", 1, lpszTempFileName) == 0 ) {
        return -1;
    }

    // ファイルの作成


    // 処理

    // 一時ファイルの削除
    ::DeleteFile(lpszTempFileName);

    return 0;
 }

解説解説:

GetTempFileNameでファイルを作成します。
もちろんですがエラーチェックを行います。

try-finallyで
tryの中の処理が中断(return)した場合でもfinallyの処理を行うようになります。
つまり中断しても一時ファイルの削除が行われます。

またfinallyでは、CreateFileのファイルハンドルを削除しています。

try-finallyは、Visual C++で書ける構文のため
それぞれの環境でこのような構文があればその形式に直してもらう必要があります。


2012/12/29 修正
GetTempFileNameでファイルが作成されるためCreateFileを行う必要がありません
おそらく実行時にエラーになると思います。

GetTempFileNameには、ファイルが作成される条件があり
第三引数(uUnique)に
 0 : ファイルは作成されない
 1 : ファイルが作成される
今回の例では、1を指定していたため作成されました・・・

__try-__finalyの使用方法にも誤りがありましたので
今回削除いたしました。

カテゴリー: バグ, プログラム | タグ: , , | コメント無し »

コメント