このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
オーバーアラインの可能性のあるクラスの演算子 new がオーバーロードされていません
割り当てられたストレージがオブジェクトのアライメント要件よりも小さい可能性がある
説明
この欠陥は、演算子 new/new[]
を適切にオーバーロードせずに、その演算子を使用して、alignas
で指定されたアライメント要件をもつオブジェクトを作成した場合に発生します。チェッカーは、以下のバージョンのスロー演算子および非スロー演算子 new/new[]
に対して欠陥を報告します。
void* operator new(std::size_t size)
void* operator new(std::size_t size, const std::nothrow_t&)
void* operator new[](std::size_t size)
void* operator new[](std::size_t size, const std::nothrow_t&)
alignas
の使用は、既定の演算子 new/new[]
がアライメント要件またはオブジェクト型が保証されることを期待していないこと、またはそのオブジェクトがオーバーアラインされる可能性があることを示します。型がオーバーアラインされるのは、alignas
を使用して、その型のアライメント要件を std::max_align_t
よりも大きくした場合です。たとえば、このコード スニペットにおいて、foo
はアライメント要件が 32 バイトであるためオーバーアラインされていますが、std::max_align_t
はほとんどの実装において 16 バイトのアライメントをもちます。
struct alignas(32) foo { char elems[32]; }
オーバーアラインの可能性のあるクラスの演算子 new がオーバーロードされていませんは、演算子 new/new[]
をオーバーロードせずに C++17 以降の規格を使用した場合、欠陥を報告しません。C++17 以降の既定の演算子 new/new[]
は、アライメント要件を std::align_val_t
型の引数として渡すことにより (たとえば、void* operator new(std::size_t size, std::align_val_t alignment)
)、オーバーアラインをサポートします。
リスク
既定の演算子 new/new[]
により、最大で std::align_val_t
となるアライメント要件がストレージに割り当てられます。オーバーアライン型をもつオブジェクトの作成時に演算子をオーバーロードしない場合、得られるオブジェクトはミスアライメントとなる可能性があります。そのオブジェクトにアクセスすると、不正アクセス エラーやプログラムの異常終了が引き起こされる可能性があります。
修正方法
C++14 以前のバージョンの規格を使用する場合、演算子 new/new[]
をオーバーロードすることにより、オーバーアラインされた型のアライメント要件をこの演算子に渡します。
例
結果情報
グループ: オブジェクト指向 |
言語: C++ |
既定値: 手書きコードはオン、生成コードはオフ |
コマンド ライン構文: MISSING_OVERLOAD_NEW_FOR_ALIGNED_OBJ |
影響度: Medium |
バージョン履歴
R2019b で導入