CL.FMM

一致しない関数でのメモリの解放

クラスレベルのチェッカーは有効な C++ のための Scott Meyer 規則クラス構築に基づいて推奨を通知します。

CL.FMM は Scott Meyer の 5 項「new と delete の対応する使用では同じ形式を使用する」に基づくものです。このチェッカーは、1 つのメカニズムを使用して割り当てられ、他のメカニズムを使用して解放されるメモリを検出します。たとえば、C とC++ のメモリ管理関数の混合使用、スカラーメモリ管理関数とベクターメモリ管理関数の混合使用です。

脆弱性とリスク

このチェッカーによって指摘される最も典型的な問題は、C++ の 'new' 演算子を使用してメモリを割り当て、C の実行時関数 'free()' を使用して割り当てを解除する場合です。この場合、そのメモリ内にオブジェクトが存在する可能性がある限り、C++ デストラクタは呼び出されません。このため、メモリは正常に割り当て解除される可能性がありますが、それはプログラマーの意図とは無関係に行われます。

また、別々の C 実装と C++ 実装が別々の基底ヒープを使用する場合、関数の混合使用は、メモリリークとヒープの破壊を容易に引き起こす可能性があります。

脆弱コード例

コピー
    class C{
      Data *data;
    public
      C(){  data = new Data[2];}
      ~C(){  delete data;}
    };

この例では、コンストラクタは演算子 'new' の配列バージョンを使用し、デストラクタはスカラーの 'delete' を使用しています。コンストラクタに割り当て済みのすべてのメモリはデストラクタ内で解放されますが、呼び出されるデストラクタは 'Data' 1つだけです。この場合、CL.FMM は、1 つのメカニズム ('new') を使用して割り当てられ、別のメカニズム ('delete') で解放されるメモリの典型的な例を検出しました。

修正コード例

コピー
    #include <iostream>
    using namespace std;
    class Data{
    public
      Data(){ cout << "Constructing Data at " << (void *)this << endl;}
      ~Data() {cout << "Destroying Data at " << (void *)this << endl;}
    };
//...
    int main(){
      C c;
      return 1;
    }
Output: 

Constructing Data at 0x602018
Constructing Data at 0x602019
Destroying Data at 0x602019

また、'new'/'delete' の実装の一部には実行時エラーを起こす可能性もあります。この問題を修正するには、解放オブジェクトに対応するメソッドを使用します。

コピー
    class C{
//...
      ~C(){  delete[] data;}
//...
    };

拡張機能

このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。