angryInsomniac
angryInsomniac

Reputation: 859

shared_ptr throwing assert when it goes out of scope

Ok, I've been trying to wrap my head around this for some time now , but I dont get it can someone please tell me why case#1 throws an assert (BLOCK TYPE IS INVALID)?

case #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)

Here's the getDependents in this case :

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

case #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)

Here's the getDependents in this case :

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

For both cases :

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

Upvotes: 1

Views: 747

Answers (2)

user1192525
user1192525

Reputation: 677

  1. is it dependents an attribute of Resource?, it seems that boost is trying to deallocate non-dynamic memory when the reference gets to zero. You could return a reference in that case.
  2. is it dependents a local variable? if so you should use dynamic memory.

Update:

Then in your case it doesn't make sense returning a shared pointer as the object dependents has not been created dynamically.

In any case, if you would need to create it dynamically, you should do the following:

In the class declaration:

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

In the constructor:

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

But in your case there is no need to use dynamic memory. I would recommend you to return a reference rather than a pointer.

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 546015

shared_ptr manages resource ownership. When you pass it a pointer you’re effectively saying “this is yours. Make sure you dispose of it when you go out of scope.”1

But then you pass it a pointer that mustn’t be disposed since it’s pointing to an object with automatic storage. This doesn’t work. Only use shared_ptr on pointers that have been created using new.2

As a consequence, the shared_ptr is trying to delete a resource that hasn’t been newed. This causes the error you observe.


1 That’s a simplification. Actually, shared_ptr manages shared ownership (= shared with other shared_ptr instances); this means that the resource will only be disposed of once all owning shared_ptrs have gone out of scope.

2 Also a simplification: there are other ways than new of obtaining resources that need to be managed, but then you need to tell shared_ptr how to manage the resource. The default disposing action is delete, which only works on newed resources.

Upvotes: 6

Related Questions