EN JP CN

CWARN.DTOR.NONVIRT.DELETE

CWARN.DTOR.NONVIRT.DELETE

仮想メソッドを持ち、仮想デストラクタを持たないクラスの式が削除されます

CWARN.DTR.NONVIRT.DELETE チェッカーは、仮想メソッドを持ち、仮想デストラクタを持たないクラスのオブジェクトの削除を検出します。

脆弱性とリスク

基本クラスから派生したクラスのオブジェクトを、その基本クラスを指すポインターを介して削除する場合、その派生クラスのデストラクタは実行されません。そして、その派生クラスのメンバーは適切に破棄されません。このような状況により、メモリのリークやリソースが解放されないといった問題につながる可能性があります。

軽減と防止

仮想メソッドと、暗黙的または明示的に適切に破棄する必要のあるメンバーデータを含むクラスに仮想デストラクタ (空であっても) を用意することが重要です。派生クラスは、基本クラスから継承します。基本クラスのデストラクタが仮想として定義されていない場合、メモリは適切に割り当て解除されません。仮想関数を宣言する、またはオーバーライドするクラスの階層では、仮想デストラクタは、その階層のルートクラスに対して 1 回だけ定義する必要があります。

脆弱コード例

1   class A
2   {
3   public:
4    
5       ~A() {cout << "I am A" << endl;}
6       virtual void f1();
7   };
8    
9   class B : public A
10  {
11  public:
12   
13      virtual ~B() {cout << "I am B" << endl;}
14      virtual void f1();
15  };
16   
17  void foo() {
18      A *a = new B;
19      delete a; 
20  }

このコード例で、クラス A に仮想デストラクタがないということは、Klocwork が 19 行目の削除にフラグを立てていることを意味します。