メインコンテンツ

以前に閉じられたリソースを閉じる

以前に閉じられたストリームを関数が閉じる

説明

この欠陥は、コード内で閉じられ、その後再開されなかったストリームを関数で閉じようとした場合に発生します。

リスク

標準では、FILE* ポインターの値は、それに関連付けられたストリームが閉じられた後に不確定となります。FILE* ポインターで閉じる操作を再度実行すると、望ましくない動作の原因となることがあります。

修正方法

冗長な閉じる操作を削除します。

すべて展開する

#include <stdio.h>

void func(char* data) {
    FILE* fp = fopen("file.txt", "w");
    if(fp!=NULL) {
        if(data)
            fputc(*data,fp);
        else
            fclose(fp);
    }
    fclose(fp);
}

この例では、fpNULL でなく dataNULL である場合、fclose 操作が fp で 2 回続けて発生します。

修正 — 閉じる操作を削除

1 つの修正方法として、後の方の fclose 操作を削除します。リソース リークを回避するために、fclose 操作を if(data) ブロックにも配置しなければなりません。

#include <stdio.h>

void func(char* data) {
    FILE* fp = fopen("file.txt", "w");
    if(fp!=NULL) {
        if(data) {
            fputc(*data,fp);
            fclose(fp);
        }
        else
            fclose(fp);
    }
}

結果情報

グループ: リソース管理
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: DOUBLE_RESOURCE_CLOSE
影響度: High

バージョン履歴

R2015b で導入