CERT.MEM.PLACEMENTNEW.TOOSMALL

十分なストレージを placement new に提供します。

脆弱性とリスク

不適切に整列されたポインターまたは不十分なストレージへのポインターを placement new 式に渡すと、バッファオーバーフローや異常終了を含む未定義の動作が発生する可能性があります。

軽減と防止

構築中のオブジェクトのアライメントが不適切なポインターを、placement new に渡さないでください。そうするとオブジェクトが不正確な位置に構築され、未定義の動作が発生します。配列に必要なオーバーヘッドを含め、構築中のオブジェクト向けのストレージ容量が不十分なポインターを渡さないでください。これにより、構築中のオブジェクトの境界外でメモリが初期化され、未定義の動作が発生する可能性があります。

最後に、placement new[] を、必要なオーバーヘッドの制限を指定していないプラットフォームで使用しないでください。

非準拠コード例

コピー
#include <new>
  
void f() {
  short s;
  long *lp = ::new (&s) long;
}

この非準拠コード例では、short へのポインターが placement new に渡され、long を初期化しようとしています。sizeof(short) < sizeof(long) のアーキテクチャでは、未定義の動作が発生します。この例と後続の例はすべて、placement new によって返されるポインターは、その基礎となるストレージの有効期間が終了した後は使用されないものと想定しています。たとえば、ポインターは静的グローバル変数に格納されず、f() の呼び出しが終了した後に逆参照されます。この想定は MEM50-CPP に準拠しています。解放されたメモリにアクセスしないでください。

準拠ソリューション

コピー
#include <new>
  
void f() {
  char c; // Used elsewhere in the function
  alignas(long) unsigned char buffer[sizeof(long)];
  long *lp = ::new (buffer) long;
  
  // ...
}

この準拠ソリューションでは、alignas 宣言指定子を使って、バッファを long に対して適切に整列します。