エラー: new-delete-type-mismatch

Address Sanitizer エラー: 割り当てサイズとは異なる割り当て解除サイズ

この例では、~Base だけが呼び出され、~Derived ではありません。 コンパイラは ~Base() への呼び出しを生成します。これは、Base デストラクターが virtual でないためです。 delete b を呼び出す場合、オブジェクトのデストラクターは既定の定義にバインドされます。 このコードは、空の基本クラス (または Windows では 1 バイト) を削除します。 デストラクター宣言に virtual キーワードが見つからないのは、継承を使用する場合の一般的な C++ エラーです。

例: 仮想デストラクター

// example1.cpp
// new-delete-type-mismatch error
#include <memory>
#include <vector>

struct T {
    T() : v(100) {}
    std::vector<int> v;
};

struct Base {};

struct Derived : public Base {
    T t;
};

int main() {
    Base *b = new Derived;

    delete b;  // Boom! 

    std::unique_ptr<Base> b1 = std::make_unique<Derived>();

    return 0;
}

ポリモーフィックな基本クラスは virtual デストラクターを宣言する必要があります。 クラスに仮想関数がある場合は、仮想デストラクターが必要です。

この例を修正するには、次を追加します。

struct Base {
  virtual ~Base() = default;
}

この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。

cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe

結果のエラー

Screenshot of debugger displaying new-delete-type-mismatch error in example 1.

関連項目

AddressSanitizer の概要
AddressSanitizer の既知の問題
AddressSanitizer のビルドと言語リファレンス
AddressSanitizer ランタイム リファレンス
AddressSanitizer シャドウ バイト
AddressSanitizer クラウドまたは分散テスト
AddressSanitizer デバッガーの統合
AddressSanitizer エラーの例