shared_ptr выбрасывает assert, когда выходит из области видимости - PullRequest
1 голос
/ 11 марта 2012

Хорошо, я пытался обернуть это вокруг себя в течение некоторого времени, но я не понимаю, может кто-нибудь, пожалуйста, скажите мне, почему случай # 1 выбрасывает утверждение (БЛОК ТИПА НЕДОПУСТИМО)?

дело № 1

mehodName()
{
    // Get all dependents for this resource
    boost::shared_ptr<std::set<std::string>> dependents = deactivatedResource->getDependendents();
    // Do some stuff 
} // Assertion thrown here (heap gets corrupted)

Вот getDependents в этом случае:

boost::shared_ptr<std::set<std::string>> Resource::getDependendents()
{
    return boost::shared_ptr<std::set<std::string>>(&dependents);
}

дело № 2

mehodName()
{
// Get all dependents for this resource
std::set<std::string>* dependents = deactivatedResource->getDependendents();
} // No problem !! (but an obvious leak , if I try to use delete ,then the same assertion as in case 1)

Вот getDependents в этом случае:

   std::set<std::string>* Resource::getDependendents()
   {
    return &dependents;
   }

Для обоих случаев:

std::set<std::string> dependents;

Ответы [ 2 ]

6 голосов
/ 11 марта 2012

shared_ptr управляет владением ресурсами.Когда вы передаете ему указатель, вы фактически говорите: «Это ваше.Убедитесь, что вы утилизируете его, когда выйдете из области видимости. ” 1

Но затем вы передаете ему указатель, который не должен утилизироваться, поскольку он указывает на объект с автоматическим хранением.Это не работаетИспользуйте shared_ptr только для указателей, которые были созданы с использованием new. 2

Как следствие, shared_ptr пытается delete ресурс, который не былnew ред.Это вызывает ошибку, которую вы наблюдаете.


1 Это упрощение.Фактически, shared_ptr управляет общим владением (= общим с другими shared_ptr экземплярами);это означает, что ресурс будет утилизирован только один раз , все , владеющие shared_ptr s, выйдут из области видимости.

2 Также упрощение: есть другие способычем new получения ресурсов, которыми нужно управлять, но затем вам нужно указать shared_ptr , как управлять ресурсом.Действие по умолчанию - delete, которое работает только на new ed ресурсах.

2 голосов
/ 11 марта 2012
  1. это dependents атрибут Resource?, Похоже, что boost пытается освободить нединамическую память, когда ссылка достигает нуля. Вы можете вернуть ссылку в этом случае.
  2. это зависимая локальная переменная? если это так, вы должны использовать динамическую память.

Обновление:

Тогда в вашем случае не имеет смысла возвращать общий указатель, так как объект dependents не был создан динамически.

В любом случае, если вам нужно будет создать его динамически, вы должны сделать следующее:

В объявлении класса:

boost::shared_ptr<std::set<std::string> > dependents;

В конструкторе:

Constructor (...) : dependents (new std::set<std::string> ()) { ... }

Но в вашем случае нет необходимости использовать динамическую память. Я бы порекомендовал вам возвращать ссылку, а не указатель.

...