C6278

警告 C6278: <変数> は配列 new [] で割り当てられていますが、スカラー delete で削除されています。 デストラクターは呼び出されません

この警告は、C++ のコードだけで発生します。呼び出し関数が配列 new [] 演算子によって一貫性のないメモリ割り当てを行い、スカラー型の delete 演算子によって解放したことを示します。 C++ 標準および Microsoft C++ の実装によると、これは未定義の動作です。 これによって問題が生じる原因は、少なくとも 3 つあります。

  • 配列内の個別のオブジェクトのコンストラクターは呼び出されますが、デストラクターは呼び出されません。

  • グローバルな (またはクラス固有の) new 演算子および delete 演算子が new[] 演算子および delete[] 演算子と互換性がない場合、予期しない結果が生じる可能性があります。

  • どのような場合でも、未定義の動作に依存することは危険です。

この問題による影響を正確に予測することは困難です。 メモリの割り当て解除を実行するデストラクターを使用するクラスでリークが発生したり、セマンティクス的に重要な操作を実行するデストラクターを使用するクラスで一貫性のない動作が行われたりする場合があります。また、演算子がオーバーライドされたときにメモリ破損およびクラッシュが発生したりする場合もあります。 コンパイラとそのライブラリの実装状態によっては、不一致が問題とならない場合もあります。 分析ツールでは、これらの状況を必ずしも判別できるわけではありません。

配列 new [] を使用してメモリが割り当てられた場合、一般的には配列 delete[] を使用して解放する必要があります。

この警告が発生するコード例を次に示します。

class A
{
  // members
};

void f( )
{
  A *pA = new A[5];
  // code ...
  delete pA;
}

この警告を解決するには、次のサンプル コードを使用します。

void f( )
{
  A *pA = new A[5];
  // code ...
  delete[] pA;
}

配列内の基になるオブジェクトが intfloatenum などのプリミティブ型であるか、ポインターである場合、デストラクターは呼び出されません。 この場合には、警告 C6283 が報告されます。

new と delete の使用には、メモリ リークと例外に関して多くの落とし穴があります。 これらのリークと例外の問題を完全に回避するには、C++ の標準テンプレート ライブラリ (STL) によって提供される機構を使用します。 これには、shared_ptrunique_ptrvector などがあります。 詳細については、「スマート ポインター」および「C++ 標準ライブラリ」を参照してください。