почему delete вызывает ошибку при использовании в "delete shared_ptr :: get ()" - PullRequest
0 голосов
/ 14 декабря 2018

Предположим, у меня есть следующий код:

#include <memory>
struct Foo{};

int main()
{
    std::shared_ptr<Foo> pf = std::make_shared<Foo>();
    delete pf.get();
    //do anything else
    return 0;
}

Почему я не могу использовать delete для непосредственного удаления объекта Foo? По моему мнению, проблема в том, что после разрушения умного указателя,delete будет вызван дважды и приведет к неопределенному поведению. Но почему это вызывает ошибку при первом использовании вручную.Я запутался, пожалуйста, помогите мне.

И я обнаружил, что возвращение get() в visual studio равно адресу выделения для реального объекта Foo из new.*

template<class... _Types>
        explicit _Ref_count_obj(_Types&&... _Args)
        : _Ref_count_base()
        {   // construct from argument list
        ::new (static_cast<void *>(&_Storage)) _Ty(_STD forward<_Types>(_Args)...);
        }

1 Ответ

0 голосов
/ 14 декабря 2018

Правильное объяснение состоит в том, что вы не получили указатель через new, поэтому вызов delete для него - неопределенное поведение, и компилятор может делать все, что захочет.

Вы даже не должныне ограничивайтесь этим.

Подробный ответ реализации (может быть изменен без уведомления, результаты могут отличаться в зависимости от версии компилятора или даже от параметров компиляции) заключается в том, что make_shared выделяет блок управления подсчетом ссылок и объект в одном выделении, а затем дает вам указатель на это распределение.Поскольку управляющему блоку обычно выделяется перед объектом, это означает, что адрес памяти, который вы передаете delete, не тот, который возвращается из распределителя памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...