2012-03-10 2 views
1

Хорошо, я уже некоторое время пытаюсь обмотать голову вокруг этого, но я не понимаю, может кто-то, пожалуйста, скажите мне, почему случай №1 выбрасывает утверждение (BLOCK TYPE ЯВЛЯЕТСЯ НЕДЕЙСТВИТЕЛЬНЫМ)?shared_ptr throwing утверждать, когда он выходит из сферы действия

дело № 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; 
+0

Что возвращает 'getDependents' (т. Е. Что делает определение этой функции)? Почему вы не используете интеллектуальные указатели последовательно? –

+1

Коррупция происходит до того, как ваш shared_ptr выходит за рамки. Используйте некоторую память, проверенную как valgrind. –

+0

Возможно, вы неправильно понимаете семантику собственности 'getDependents'. Проверьте документацию и/или код. –

ответ

2
  1. это dependents атрибут Resource, кажется, что подталкивание пытается освободить без динамической памяти, когда задание получает к нулю. Вы можете вернуть ссылку в этом случае.
  2. Это иждивенцы локальной переменной? если это так, вы должны использовать динамическую память.

Update:

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

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

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

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

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

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

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

6

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

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

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


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

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

+0

Ребята в чате C++, похоже, думают иначе! и, как говорится в названии, можно предположить, что указатель разделяется! – angryInsomniac

+0

@angryInsomniac См. Обновление. Я (намеренно) упрощал, но потом понял, что требуется уточнение. –

+0

Ссылка № 1 Если он управляет общим достоянием, и этот объект также находится в другом месте, то почему этот контекст пытается его удалить? – angryInsomniac

Смежные вопросы