Поделиться через


Ошибка: new-delete-type-mismatch

Ошибка санитизатора адресов: размер сделки отличается от размера выделения

В этом примере вызывается только и ~Baseне ~Derivedвызывается. Компилятор создает вызов ~Base() , так как Base деструктор не virtualявляется. При вызове delete bдеструктор объекта привязан к определению по умолчанию. Код удаляет пустой базовый класс (или 1 байт в Windows). 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

Результирующая ошибка

Снимок экрана: отладчик, отображающий ошибку несоответствия типа new-delete в примере 1.

См. также

Обзор AddressSanitizer
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Справочник по среде выполнения AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer