Оборванная ссылка для умного указателя в C ++ - PullRequest
1 голос
/ 09 апреля 2020

Я понимаю, что в C ++ лучше / безопаснее использовать умные указатели, чтобы убедиться, что мы никогда не пропустим освобождение / удаление выделенной памяти. Недавно я наткнулся на следующее в лекции о интеллектуальных указателях на C ++. Вот пример:

void test_pointer(void)
{
    typedef std::shared_ptr<MyObject> MyObjectPtr;
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        p1 = p2;
    }
}

Теперь я понимаю, что std:shared_ptr будет уничтожено после последней ссылки на него, ie после выхода из функции p1 будет уничтожено. Но предупреждение в конце было о висячей ссылке, что меня смутило:

MyObjectPtr* pp = new MyObjectPtr(new MyObject());

В примечании упоминается, что если это было объявлено внутри функции, то это висячая ссылка, которая предотвращает std::shared_ptr от того, чтобы быть удаленным. Это почему? Мы используем умные указатели, поэтому мы никогда не должны оказаться в такой ситуации?

Ответы [ 2 ]

3 голосов
/ 09 апреля 2020

Как получилось? Мы используем умные указатели, поэтому мы никогда не должны оказаться в этой ситуации?

Вы не. Здесь:

MyObjectPtr* pp = new MyObjectPtr(new MyObject());

Вы используете необработанный указатель на объект, тип которого является интеллектуальным указателем. Но это не имеет значения, какой тип объекта вы выделяете вручную и храните в необработанный указатель - вы должны управлять временем жизни этого объекта вручную. Или используйте умный указатель.

3 голосов
/ 09 апреля 2020

Я только что понял (и, пожалуйста, исправьте меня, если я ошибаюсь):

Мы используем необработанный указатель на std::shared_ptr, который никогда не освобождается, что и является причиной проблемы. Это никогда не было освобождено. и поскольку это происходит в функции, то она также предотвращает уничтожение p1.

...