Увеличить назначение Shared_Ptr - PullRequest
6 голосов
/ 30 сентября 2010

Почему я не могу этого сделать?

boost::shared_ptr<QueuList> next;

void QueuList::SetNextPtr(QueuList* Next)
{
    boost::mutex mtx;

    boost::mutex::scoped_lock lock(mtx);
    {// scope of lock
        //if (next == NULL)  // is this needed on a shared_ptr??
        next = Next;  // Why can I not assign a raw ptr to a shared_ptr????
    }

}

Как мне сделать это вместо этого?

EDIT: вызов этого метода, когда следующая переменная назначена правильно, все равно вызывает ошибку, когда объект QueuList по какой-то причине уничтожается. Я получаю отладочное утверждение. Деструктор объекта не делает ничего особенного. Вылетает только когда я вызываю эту функцию:

    QueuList li;
    QueuList lis;

    li.SetNextPtr(&lis);

Когда main выходит из области видимости, я получаю отладочное утверждение ... Есть идеи ??

Ответы [ 3 ]

7 голосов
/ 30 сентября 2010

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

next = boost::shared_ptr<QueueList>( Next );

Правка для редактирования Проблема в том, что в вашем случае shared_ptr становится владельцемобъект в стеке.Тогда могут произойти две вещи:

  1. Фрейм стека объекта очищается до того, как shared_ptr достигнет счетчика ссылок 0. В этом случае shared_ptr попытается удалить не-существующий объект где-то позже, приводящий к неопределенному поведению.
  2. shared_ptr достигает счетчика ссылок 0, прежде чем очищается кадр стека.В этом случае он попытается удалить объект в стеке.Я не знаю точно, что происходит в этом случае, но я бы предположил, что это тоже неопределенное поведение.
6 голосов
/ 30 сентября 2010

Вы можете использовать функцию Reset () вместо wordier next = boost::shared_ptr<QueueList>(Next);

next.Reset(Next);
5 голосов
/ 30 сентября 2010

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

some_shared_ptr = some_other_smart_pointer.get();

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

Вот что происходит с вашим утверждением об отладке.Вызов SetNextPtr(&lis) передает владение &lis на shared_ptr, а «владение» означает, что shared_ptr будет вызывать delete для своего коммутатора, когда последняя копия shared_ptr выйдет из области видимости.Таким образом, вы фактически удаляете локальную (стековую) переменную - lis - которая разрушает стек и вызывает сбой.

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