Im working on this project,
The problem Im having is that the an object, does not really get deleted when I need it to be because it has a couple of shared pointers pointing to it.
How do I solve this,please help.
This is by design. As long as an object is owned by one or more shared_ptr smart pointers, it will not be destroyed. Ownership of the object is shared by all of the smart pointers that have ownership and the object can't be destroyed until all of the owners are done with it. This is what shared ownership is.
If you want to be able to destroy the object while there are still some references to it, you can use weak_ptr for those references.
You can decrease the use_count of a shared_ptr by using its reset() method.
If you do this for every pointer which holds the instance, the last reset() will destroy the object it points to.
shared_ptr<Class> myPointer1( new Class() ); //myPointer holds an instance of Class
shared_ptr<Class> myPointer2 = myPointer1; //use_count == 2
myPointer1.reset(); //use_count == 1
myPointer2.reset(); //instance of class will be destroyed
But you probably have a problem with you design, shared_ptr should automatically go out of focus when certain objects are destroyed or methods end. Perhaps you should have a look at the points where the shared_ptrs still hold pointers to the object and check if they shouldn't hold the object anymore.
Related
I wanted to use a smart pointer like shared_ptr of std library but where
it would be possible to delete the object for every shared_ptr that share it
without deleting those pointers.
For example if i use std::shared_ptr
shared_ptr<A> p1 = make_share<A>();
shared_ptr<A> p2 = shared_ptr<A>(p1);
p1.reset();
// now p2 still contain the object of type A
// instead of nullptr
Is there a way to do that or does some alternatives exist? Am i doing it wrong?
Absolutely. std::shared_ptr comes with std::weak_ptr, a pointer that can point to an object managed by a set of std::shared_ptrs and check whether it is still alive, but does not extends the object's lifetime.
You just have to keep the original std::shared_ptr to your object, and lend std::weak_ptrs to other users of that object. When the object must be destroyed, reset the std::shared_ptr, and all remaining std::weak_ptrs will be able to tell (they'll return null std::shared_ptrs when the users try to lock them).
I have a vector of pointers to other "objects" in a class.
Is there any way, after/when one of those objects gets deleted to remove any pointer that might have been pointing to it from the vector?
The best thing would be to propagate the deletion somehow but, it would also be okay to just know an object has been deleted whenever the vector gets traversed.
Do not use vanilla pointers. Use the classes std::shared_ptr and std::weak_ptr instead.
These classes implement automatic memory management. When you don't need an object anymore, you don't delete the object, you delete all the shared_ptrs which reference that object. Only when no shared_ptrs to an object exist anymore, the actual object will get deleted.
Any weak_ptrs which still exist will return an object which will evaluate as false. When that happens, you know the weak_ptr can be removed from the vector.
That's why std::weak_ptr exists. It doesn't stop deletion, but it does detect it.
I have a class derived from std::enable_shared_from_this. All class objects are managed by shared pointers, thus they get destructed automatically when there are no more shared pointers pointing to them.
I have a class method which removes some shared pointers from the program's data structures, and there's a risk it removes all shared pointers to "this", i.e. the object on which the class method was called.
The question is, if really all pointers are removed, is there a chance the object is destroyed while the method runs, and the "this" pointer simply becomes invalid? If I want to ensure it doesn't happen, can I trust the system or I have to create a shared_ptr to "this" inside the method, to keep the object alive until I'm done with it? (And then if there's no more pointers, it's okay to have it destructed, once the method execution ends)
EXAMPLE:
class SharedObj : public std::enable_shared_from_this<SharedObj>
{
/* ... */
void do_something(SharedObj& a, SharedObj& b);
std::shared_ptr<SharedObj> child;
};
void SharedObj::do_something(SharedObj& a, SharedObj &b)
{
/* ... */
a.remove_child();
b.remove_child();
}
If a and b are the only ones who have a shared_ptr pointing to "this", then after the two remove_child() rows, there are no shared pointers pointing to "this", so besically it's supposed to be automatically destructed
You certainly can wind up destructing your instance from within a method by doing what you're doing. But this situation isn't specific to enable_shared_from_this, you can always call something in a method that can result in your own class's destruction. This is really only an error if you try to deference this after your class is destroyed. If you go on with regular code that doesn't modify or access the class instance, you are safe.
What you suggested (to hold a shared_ptr to your own instance during do_something's execution) is a good idea, if you need the instance to persist for the entire function execution.
As an alternative or in addition to Dave's answer if you are using shared pointers throughout for managing lifetimes then you should only ever be calling the object through a shared pointer anyway so that pointer will be keeping the object alive until after the function returns. If you store a non-owning pointer to a shared pointer managed object then you should be storing a weak pointer and locking it before using it. That shared pointer created by locking will again keep the object alive.
I have an array of pointers: pArray[rows][columns], where each element can contain a pointer to an object. Some of the objects were instantiated in main() on the heap, and some were instantiated by objects themselves also on the heap: That is, I passed pArray to an object member function, and that function created a new object, and put a pointer to it in pArray.
Now when I want to delete pointers to objects from pArray, is there ownership in play here? Meaning, if an object created a new object and placed a pointer to it in pArray, can only the creator object call delete on that pointer? Or can I do it from main(), and other objects by passing the array to them?
Some more details:
The code simulates a predator prey model on a grid (pArray). So I begin by reading in the initial grid config from a file, and instantiate objects (predators, and prey), on pArray from main(). But predators and prey can breed, so objects spawn new objects and by passing pArray to them, they instantiate their children on pArray.
With raw pointers ownership is purely a concept. As long as you are working with raw pointers, it is entirely up to you to assign ownership of pointed object to anyone and anything. It is a matter of your design. There's no such "rule" that the object should be deleted by whoever created them. Ownership can be retained or passed on. Ownership can be shared (as in reference-counted ownership schemes). Again, it is a matter of your design and your intent.
Various smart pointer classes will help you to express your intent and implement your intent. With raw pointers you have to remember who owns what and do everything manually.
No, there is no "ownership" on pointers in C++, if the pointer is valid (contains proper reference to data / object), you can deallocate it anywhere issuing delete command.
The destructor of objects is subject to the same public/protected/private like every other method. So, if the destructor is public, anyone can call delete on the object.
The only important thing is that it happens exactly once, and only after nobody is using the object anymore.
There is no ownership concept for pointers in C++ .As far as I understood your question, Yes you can delete that object from main() in case of dynamic memory allocation. The memory allocated to that object would only be freed only when the program ends or the Object array goes out of scope and the destructor for the class is called.
Will the smart pointer or scoped pointers delete an object when the class has no destructor
If not, why not just leave the scope and let the object be deleted by itself?
All class members are deleted even if you don't have a destructor when the instance is deleted. Memory leaks occur when you deal with pointers:
class A
{
private:
B* b;
};
In this case, b itself will be destroyed when the instance of A is deleted, but the memory it points to will not.
class A
{
private:
SmartPtr<B> b;
};
In the case of smart pointers, which usually have some reference counting and memory cleanup in the destructor, the memory it points to will be explicitly destroyed by its destructor, and the destructor of the smart pointer will be implicitly called when the instance of the containing class is destroyed.
yes. that s what smart pointers are used for.
http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/smart_ptr.htm
http://en.wikipedia.org/wiki/Smart_pointer
What is a smart pointer and when should I use one?
Yes, smart pointer deletes the object irrespective of whether class has destructor or not. Note that smart pointers are used with objects allocated on heap (using new) and these object won't release memory when they go out of scope, you need to explicitly delete them. Smart pointers will remove this process of explicitly deleting them.
The pointer to the object itself will be deleted. However if there is any dynamically allocated data in the class it will not get freed. The idea of having a destructor is to be able to post-process the class object and mainly - free any resources taken.
new and delete do two things.
new allocates memory and gets an object to construct itself in that memory space.
delete first gets the object to destruct itself then releases the memory.
Note that some smart pointers can be given a custom deleter which doesn't call delete on the object but whatever you ask it to do. There may be occasions when you wish to pass it a no-op.
Your point is well taken; there aren't that many uses for smart pointers
in C++, since most of the time where they might be relevant, you'd be
better off using value semantics, and copying. In the case of
scoped_ptr, the most frequent use is when the actual object is
polymorphic:
scoped_ptr<Base> pObj = condition
? static_cast<Base*>( new Derived1 )
: static_cast<Base*>( new Derived2 );
(Regretfully, at least one of the static_cast is necessary.)
If you are dealing with a container of polymorphic objects, you'll need
shared_ptr instead, and if you're returning a polymorphic object, or
otherwise passing it around, you will use unique_ptr if you can
guarantee its availability, and auto_ptr otherwise—in some cases
where you're passing it around, shared_ptr might be more appropriate.
In the case of returning an object or passing it around, the cost of
copying it might also be a motive for using a smart pointer, even if the
object isn't polymorphic. In such cases, I'd still use value semantics
(i.e. copying and assigning the object itself) unless I had a
performance problem.
Note that smart pointers aren't only used for memory management. I
regularly use auto_ptr in the interface of queues between threads:
once the object has been inserted into the queue, it no longer belongs
to the sending thread; auto_ptr expresses these semantics exactly,
with the auto_ptr in the sending thread becoming invalid. Or a
modifiable singleton (something which should be very, very rare) might
acquire a lock in its instance function, and return a shared_ptr
which frees the lock in its final destructor. I've also used smart
pointers in one or two cases to ensure transactional semantics: in one
case, for example, the objects were in a number of different sets (which
held pointers to them, of course), ordered according to different
criteria. To modify an object, you acquired a shared pointer to it; the
function which returned this shared pointer also removed the objects
from the sets, so that you could safely modify the key values as well,
and the final destructor reinserted them into the sets according to the
new keys. And so on—there are any number of uses for smart
pointers that have nothing to do with memory management or object
lifetime.