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 に対して適切に整列します。