CERT.MEM.OBJ_LIFETIME_CTOR

初期化されていない heap メンバー関数の呼び出し

CERT.MEM.OBJ_LIFETIME_CTOR チェッカーは、最初に初期化されずにメンバー関数を呼び出す、メモリが new 演算子なしに動的に割り当てられるユーザー定義オブジェクトを探します。

脆弱性とリスク

オブジェクトは、new 演算子を使用せずに、malloc などを使用して、ヒープ上に割り当てられ、自明なコンストラクターがない場合は、初期化されません。そのオブジェクトのメンバー関数を呼び出すことは未定義の動作とみなされます。これは、オブジェクトの有効期間がまだ開始されていないためです。

軽減と防止

適合のための解決策は、new 演算子を使用してメモリを割り当てることです。そうすれば、コンストラクターも呼び出されるようになります。もう 1 つの選択肢は、メモリが割り当てられた後にコンストラクターを明示的に呼び出すことです。

脆弱コード例

コピー
#include <cstdlib>
 
struct S {
  S(){}
  void f(){}
};
 
void g() {
  S *s = static_cast<S *>(std::malloc(sizeof(S)));
  s->f();
  std::free(s);
}

Klocwork で 10 行目について欠陥 CERT.MEM.OBJ_LIFETIME_CTOR が報告され、「初期化されずに動的に割り当てられたオブジェクト 's' へのポインターがメンバー関数 'f' の呼び出しに使用されている」ことが示されます。 このコードでは、オブジェクトが初期化される前にメンバー関数 'f' が呼び出されます。

修正コード例

コピー
#include <cstdlib>
 
struct S {
  S(){}
  void f(){}
};
 
void g() {
  S *s = static_cast<S *>(std::malloc(sizeof(S)));
  s = new (s) S;
  std::free(s);
}

コードでコンストラクターが明示的に呼び出されるので、オブジェクトが使用される前にオブジェクトの有効期間が開始され、欠陥が回避されるようになっています。