Я наткнулся на следующий фрагмент кода:
#include <iostream>
#include <string>
using namespace std;
class First
{
string *s;
public:
First() { s = new string("Text");}
~First() { delete s;}
void Print(){ cout<<*s;}
};
int main()
{
First FirstObject;
FirstObject.Print();
FirstObject.~First();
}
В тексте сказано, что этот фрагмент должен вызвать ошибку во время выполнения. Теперь я не был уверен в этом, поэтому я попытался скомпилировать и запустить его. Это сработало. Странная вещь, несмотря на простоту используемых данных, программа заикалась после печати "Текст" и только через одну секунду она завершила.
Я добавил строку, которая должна быть напечатана в деструкторе, так как я был не уверен, было ли законным явно вызывать деструктор таким образом. Программа напечатала дважды строку. Поэтому я предположил, что деструктор вызывается дважды, поскольку обычное завершение программы не знает явного вызова и пытается снова уничтожить объект.
Простой поиск подтвердил, что явный вызов деструктора для автоматизированного объекта опасен, поскольку второй вызов (когда объект выходит из области видимости) имеет неопределенное поведение. Так что мне повезло с моим компилятором (VS 2017) или этой конкретной программой.
Является ли текст просто неправильно об ошибке во время выполнения? Или это действительно распространенная ошибка? Или, может быть, мой компилятор реализовал какой-то механизм защиты от подобных вещей?