警告 C26407
スコープ付きオブジェクトを優先し、不必要にヒープ割り当てしない (r.5)
ポインターの不必要な使用を避けるために、Microsoft ではローカル割り当ての一般的なパターンを検出しようとしています。 たとえば、演算子 new
の呼び出しの結果がローカル変数に格納され、後で明示的に削除されるというケースを検出します。 このチェックは、C++ Core Guidelines ルール R.5 をサポートしています。スコープオブジェクトを優先し、不必要にヒープ割り当てしないでください。 この問題を解決するには、生のポインターではなく RAII 型を使用し、それがリソースを処理できるようにします。 当然ながら、1 つのオブジェクトを割り当てるために、ラッパー型を作成する必要はありません。 代わりに、オブジェクトの型のローカル変数の方が適切に機能します。
解説
警告の数を減らすために、コード分析では、所有者ポインターについてのみこのパターンが検出されます。 そのため、最初に所有者を適切にマークする必要があります。 このようなシナリオをサポートしているお客様から Visual Studio C++ 開発者コミュニティ に関するフィードバックを受け取った場合は、生のポインターをカバーするようにこの分析を簡単に拡張できます。
スコープ付きオブジェクトという用語は、少し誤解を招くおそれがあります。 一般に、有効期間が自動的に管理されるローカル変数か、動的リソースを効率的に管理するスマート オブジェクトのいずれかを使用することをお勧めします。 スマート オブジェクトはヒープ割り当てを実行できますが、コードでは明示的ではありません。
動的バッファーに必要な配列の割り当てで警告が発生した場合は、標準コンテナーを使用して修正するか、または
std::unique_pointer<T[]>
.このパターンは、ローカル変数についてのみ検出されます。 割り当てがグローバル変数に割り当てられ、同じ関数で削除された場合は警告しません。
コード分析名: DONT_HEAP_ALLOCATE_UNNECESSARILY
例 1: ヒープ上での不必要なオブジェクトの割り当て
auto tracer = new Tracer();
ScanObjects(tracer);
delete tracer; // C26407
例 2: ヒープ上での不必要なオブジェクトの割り当て (ローカル オブジェクトを使用して修正)
Tracer tracer; // OK
ScanObjects(&tracer);
例 3: ヒープ上での不必要なバッファーの割り当て
auto value = new char[maxValueSize];
if (ReadSetting(name, value, maxValueSize))
CheckValue(value);
delete[] value; // C26407
例 4: ヒープ上での不必要なバッファー割り当て (コンテナーを使用して修正)
auto value = std::vector<char>(maxValueSize); // OK
if (ReadSetting(name, value.data(), maxValueSize))
CheckValue(value.data());