Виртуальные деструкторы при нестандартном управлении памятью
От: Ester  
Дата: 28.03.22 08:23
Оценка: -1
Это сообщение — комментарий к странице "Deep C++ > А чисто виртуальные деструкторы
Автор: Павел Кузнецов
Дата: 03.04.03
— бывают?"
, но она закрыта? (

У многих компиляторов вызов виртуальных деструкторов при нестандартном управлении памятью происходит неправильно. cl выдержал все проверки, только со второй формой оператора delete, по видимости, есть некоторые проблемы:
  Текст virtual destructors.cpp
#include <stddef.h>
#include <stdio.h>

class A {
    int ma;
public:
    A ();
    virtual ~A ();
    void *operator new (size_t size);
    void operator delete (void *p, size_t size);
    void *operator new [] (size_t size) { return operator new (size); }
    void operator delete [] (void *p, size_t size) { operator delete (p, size); }
};

class B : public A {
    int mb;
public:
    B ();
    virtual ~B ();
};

int main ()
{
    A *pa = new B;
    delete pa;
    A *paa = new B [2];
    delete [] paa;
    return 0;
}

A::A  () { printf ("A::A()\n"); }
B::B  () { printf ("B::B()\n"); }
A::~A () { printf ("A::~A()\n"); }
B::~B () { printf ("B::~B()\n"); }

void* A::operator new (size_t size) 
{
    void *p;
    p = ::operator new (size);
    printf ("A::operator new (%u) = <%08x>\n", size, p);
    return p;
}

void A::operator delete (void *p, size_t size)
{
    ::operator delete (p);
    printf ("A::operator delete (<%08x>, %u)\n", p, size);
}

Результаты работы:
  Результаты
Оптимизирующий 32-разрядный компилятор Microsoft (R) C/C++ версии 16.00.30319.01 для 80x86:
A::operator new (12) = <00334fc8>
A::A()  B::B ()  B::~B ()  A::~A()
A::operator delete (<00334fc8>, 12)
A::operator new (28) = <003328b8>
A::A ()  B::B ()  A::A ()  B::B ()
B::~B()  A::~A()  B::~B()  A::~A()
A::operator delete (<003328b8>, 12)

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86:
A::operator new (12) = <00332bc8>
A::A()  B::B() B::~B() A::~A()
A::operator delete (<00332bc8>, 12)
A::operator new (28) = <00332be0>
A::A ()  B::B ()  A::A ()  B::B ()
B::~B()  A::~A()  B::~B()  A::~A()
A::operator delete (<00332be0>, 12)

Intel(R) C++ Compiler for 32-bit applications, Version 9.0:
A::operator new (12) = <00333db8>
A::A()  B::B()  B::~B()  A::~A()
A::operator delete (<00333db8>, 12)
A::operator new (28) = <00332bb0>
A::A()  B::B()  A::A()  B::B()  A::~A()  A::~A()
A::operator delete (<00332bb0>, 0)

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland:
A::operator new (12) = <00852d14>
A::A()  B::B()  B::~B()  A::~A()
A::operator delete (<00852d14>, 12)
A::operator new (28) = <00852d14>
A::A()  B::B()  A::A()  B::B()  A::~A()  A::~A()
A::operator delete (<00852d14>, 16)

Borland C++ 5.0 Copyright (c) 1987, 1996 Borland International:
A::operator new (6) = <00000e42>
A::A()  B::B()  B::~B()  A::~A()
A::operator delete (<00000e42>, 6)
A::operator new (16) = <00000e42>
A::A ()  B::B ()  A::A ()  B::B ()
A::~A()  A::~A()  A::~A()  A::~A()
A::operator delete (<00000e42>, 8)

Borland C++  Version 3.1 Copyright (c) 1992 Borland International
A::operator new (6) = <000005e2>
A::A()  B::B()  B::~B()  A::~A()
A::operator delete (<000005e2>, 6)
A::A()  B::B()  A::A()  B::B()  A::~A()  A::~A()


Borland провалился, даже у Intel 9 версии ошибки.

При современной технике программирования деструкторы следует объявлять виртуальными всегда.
Отредактировано 28.03.2022 9:07 Ester . Предыдущая версия .
c++
Re: Виртуальные деструкторы при нестандартном управлении памятью
От: Chorkov Россия  
Дата: 28.03.22 11:12
Оценка: +4
Здравствуйте, Ester, Вы писали:

см. https://isocpp.org/files/papers/N4860.pdf

7.6.2.8 Delete

...
3. In a single-object delete expression, if the static type of the object to be deleted is different from its dynamic
type and the selected deallocation function (see below) is not a destroying operator delete, the static type
shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual
destructor or the behavior is undefined. In an array delete expression, if the dynamic type of the object to be
deleted differs from its static type, the behavior is undefined.


Какое управление памятью уже не важно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.