Вызов `delete` для объекта, принадлежащего` unique_ptr`, с использованием другого указателя - PullRequest
0 голосов
/ 21 октября 2018

У меня есть указатель на класс, инициализированный оператором new.Затем я использую этот указатель для установки std::unique_ptr.Теперь, насколько я понимаю, следующий код имеет двойное удаление, один раз вызванный вручную оператор delete, а затем, когда уникальный указатель выходит из области видимости.Как этот код работает «правильно», то есть без исключения времени выполнения?

#include <iostream>
#include <memory>

class A
{
public:
    A()
    {
        std::cout<<"In A::A()\n";
    }
    ~A()
    {
        std::cout<<"In A::~A()\n";
    }
    void printMyStr()
    {
        std::cout<<"In A::printMyStr()\n";
    }
};

int main()
{
    std::cout<<"hello world!\n";
    A * pa = new A();
    std::unique_ptr<A> upa(pa);
    pa->printMyStr();
    upa->printMyStr();
    delete pa;  // How does this not create problems?
    return 0;
}

Вывод:

hello world!
In A::A()
In A::printMyStr()
In A::printMyStr()
In A::~A()
In A::~A()

Очевидно, деструктор запускается дважды, даже если существует только один объект, которыйсоздано.Как это возможно?

Примечание: я использую gcc 7.3.0 на 64-битной Linux.

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Если в какой-то момент до того как экземпляр unique_ptr выйдет из области видимости, вы решите удалить управляемый объект, просто выполните unique_ptr_instance.reset(nullptr).Это вызывает средство удаления и приводит к тому, что управляемый объект становится nullptr, удаление которого, когда экземпляр, наконец, выходит из области видимости, является невозможным.

0 голосов
/ 21 октября 2018

Двойное удаление - неопределенное поведение.

Неопределенное поведение не гарантирует исключение времени выполнения;это будет определено.Неопределенное поведение означает, что все может случиться.Это может включать в себя путешествия во времени, форматирование жестких дисков, отправку истории браузера по электронной почте вашим контактам или вообще ничего.

Мне еще не приходилось получать историю браузера по электронной почте, о которой я знаю.Я пережил остальное.

...