Udostępnij za pośrednictwem


Błąd: new-delete-type-mismatch

Błąd narzędzia do oczyszczania adresu: rozmiar cofania różni się od rozmiaru alokacji

W tym przykładzie wywoływana jest tylko ~Basenazwa , a nie ~Derived, . Kompilator generuje wywołanie metody , ~Base() ponieważ Base destruktor nie virtualjest . Gdy wywołujemy delete bmetodę , destruktor obiektu jest powiązany z definicją domyślną. Kod usuwa pustą klasę bazową (lub 1 bajt w systemie Windows). Brakujące virtual słowo kluczowe w deklaracji destruktora jest typowym błędem języka C++ podczas korzystania z dziedziczenia.

Przykład — destruktor wirtualny

// 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;
}

Klasy bazowe polimorficzne powinny destruktory destruktorów virtual . Jeśli klasa ma jakiekolwiek funkcje wirtualne, powinna mieć destruktor wirtualny.

Aby rozwiązać ten przykład, dodaj:

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

Aby skompilować i przetestować ten przykład, uruchom następujące polecenia w wierszu polecenia programu Visual Studio 2019 w wersji 16.9 lub nowszej:

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

Wynikowy błąd

Zrzut ekranu przedstawiający debuger wyświetlający błąd niezgodności typu new-delete-type w przykładzie 1.

Zobacz też

AddressSanitizer — omówienie
Rozwiązywanie znanych problemów z programemSanitizer
Dokumentacja języka i kompilacji narzędzia AddressSanitizer
AddressSanitizer runtime reference (Dokumentacja środowiska uruchomieniowego AddressSanitizer)
Bajty w tle addressSanitizer
AddressSanitizer — chmura lub testowanie rozproszone
Integracja debugera AddressSanitizer
Przykłady błędów addressSanitizer