Используя указатель, возвращенный функцией std :: shared_ptr <T>.get (), чтобы удалить объект? - PullRequest
0 голосов
/ 26 марта 2020
int main(int argc, char *argv[])
{
    auto sp = std::make_shared<int>();
    auto p = sp.get();
    delete p; //here
    std::cout << *sp << std::endl;

    return 0;
}

Я надеялся, что объект, управляемый shared_ptr sp, будет удален оператором, закомментированным «здесь», но объект останется нетронутым и будет напечатан в выходном операторе.

  • Разве это не работает, потому что я не создал объект, управляемый shared_ptr явно с ключевым словом new (потому что каждый оператор new должен иметь соответствующий оператор delete и поэтому каждый оператор delete, ранее соответствующее ключевое слово new?)?
  • И означает ли это, что указанные объекты, управляемые shared_ptr s, созданные из функции make_shared, уничтожаются только shared_ptr s сами?

Ответы [ 3 ]

3 голосов
/ 26 марта 2020

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

delete помечает память, занятую объектом, как «свободную для повторного использования» и вызывает деструктор объектов. После delete вам не разрешено (под угрозой вызова UB) когда-либо снова обращаться к объекту.

Ваша программа просто недопустима и что-нибудь компилятор может генерация разрешена.

2 голосов
/ 26 марта 2020

Способ «управления» памятью, связанной с shared_ptr, заключается в использовании области видимости C ++, часто называемой RAII ( R esource A cquisition I s I нитиализация).

Для вашего кода:

int main(int argc, char *argv[])
{
    {
       auto sp = std::make_shared<int>();
       std::cout << *sp << std::endl;
    }
    // memory is now delete'd because "sp" is out-of-scope

    return 0;
}

С shared_ptr все может быть (совсем немного) более сложный, чем несколько shared_ptr s могут указывать на одну и ту же память; только когда последний один утерян, память удаляется.

Вы должны использовать std::unique_ptr, пока вам действительно не понадобится shared_ptr.

0 голосов
/ 26 марта 2020

Во-первых, если вы сделаете это, ваш объект будет удален дважды, и вам повезет sh, если вам повезет.

Во-вторых, только то, что что-то было удалено, не означает, что оно лежит в основе представление гарантированно будет недействительным. Может возникнуть ситуация, когда память освобождается, но еще ничего не пришло, чтобы перезаписать то, что было раньше.

...