I am pretty new to C++11 and am now working on improving my C++ skills by trying to avoid direct usage of pointers. I am trying to write a sprite manager that keeps track of previously loaded sprites and frees unused ones. I am trying to use shared_ptr (pointer to the bitmap) for this, but the manager also has to keep a shared_ptr to create the sprites with - so the reference count doesn't drop to 0. Can I somehow declare the "parent" shared_ptr in my manager non-owning so it doesn't count as a reference (and still create owning copies of that shared_ptr)?
Use a weak_ptr. That will solve your problem. You won't need to free them as they will be automatically freed. Use a lock on the weak_ptr to get an actual shared_ptr.
The use_count will also give you the current number of references.
shared_ptr are made to be owning. If you want a non-owning pointer at some part of your prgram use weak_ptr like so:
std::shared_ptr<Object> sp(new Object);
std::weak_ptr<Object>(sp);
You're trying to do a kind of "backseat driver" style of memory management; you want to use shared-ptr, but you also want to control when shared_ptr frees resources!
There are a couple of obvious things you could do here.
Just use shared_ptr and don't bother with any sort of memory management or resource ownership in your sprite manager class. Trust shared_ptr to do its job. If you need to know when a resource is destroyed, you can always use the observer pattern or the like, and have your resource class message the manager when it is destroyed. Of course, this means you can't ask your sprite manager to provide additional references to an existing sprite, which isn't so great.
Write your own smart pointer. It isn't necessarily trivial, but writing a resource-specific reference-counting smart pointer isn't rocket science (its a hell of a lot simpler than writing something like shared_ptr, for example). The manager can then terminate resources when there's only a single reference to them remaining (eg. its own reference).
Everyone else has already mentioned weak_ptr. Has all of the benefits of (1), only you can create additional shared_ptr instances referencing the same underlying resource.
You might also want to consider resource usage patterns, and the cost of loading resources. You may not necessarily want to destroy a resource as soon as your application stops referencing it; if it is requested again a second later, it might take some time to reload it. Lazily freeing resources when they've gone unused for a little while might be a better approach. Just a thought.
Related
I've been thinking that while I understand the goals of std::observer_ptr I think it would be nice if there was at least an option for a similar pointer type that knows if what it points to has been deleted. For example, we could have something like the following
slightly_smart_ptr<Foo> p1(new Foo());
auto p2 = p1;
p1.erase(); // This deletes the foo referred to by p1.
if (p2.expired())
std::cout << "p2 is expired\n"; // this will fire
One way to achieve this with the current standard library is to make a shared_ptr to A in some scope that will exist for the lifetime of A, always refer to A by passing weak_ptrs around, and delete A when it is no longer needed by resetting the shared_ptr. The weak_ptrs here will have the basic semantics of observer_ptrs that know if A has been deleted. But there are problems with this approach: weak_ptrs must be locked, turning them into shared_ptrs to be used, which feels untidy, but more seriously a shared_ptr to A must exist somewhere, when all the user wants is a slightly smart pointer that does not own any content. The user agrees to manually destroy the content when it is time: no ownership is shared so it is a code smell for the user to create a shared_ptr in such a situation.
I however cannot think of a way in which the details of this implementation could be effectively hidden.
Also does such a pointer exist as a proposal or in a boost library or elsewhere?
The problem of such smart pointer is that it would be more error prone than std::unique_ptr, T* or std::weak_ptr.
When you want to know if a pointer has been deleted from elsewhere by it's unique owner, in reality you need shared ownership and std::weak_ptr.
You see, there is a reason why you need to "lock" a weak pointer before using it. It's because when you start using it, you gain ownership of the pointer. If you cannot lock your "observer pointer that knows if deleted or not", you cannot safely use it, since at any moment after verifying it's validity, it can be deleted.
Also, you have a deeper contradiction.
When you have a unique pointer, you know who is gonna delete it, and you know who is the owner.
If you have a program that checks for the validity of a pointer at runtime, then it's because your program doesn't know the state of the ownership of the resource.
If your program or parts of your program cannot know the state of the ownership of a resource and need to check if it had been deleted or not, then you need to ensure that it won't be deleted the next line while using it, since it can be deleted at any time, since you cannot know about its ownership status. Therefore you need to own the resource temporarily while using it. Therefore you need shared ownership to defer the ownership decision while executing the code.
If you have shared ownership, you don't need a observer pointer that knows if deleted or not.
Your pointer don't need to exist then.
So... you thought you need that pointer, it could be handy... what can you do?
You need to review your code. If there is a single ownership, why do you need to know the validity of the pointer. Why cannot you simply ask the owner?
If the owner don't exist, maybe your code that want to do the check should not be valid when the owner is deleted. Maybe your structure that want to do the check should die at the same time as the owner.
If your unique owner dies at an unpredictable moment (for example, your unique owner is held by a shared owner) then maybe your structure should check the validity of the shared owner instead.
Maybe your code calling the function that want to check if its pointer is still valid should simply not call it when there owner is dead.
...
And so on.
There is so many ways to solve that, but needing a weak pointer on a unique owner usually shows a flaw in the program or a problem in the reasoning of the lifetime of the objects in your program.
Not feasible in general.
The entire purpose of the extant smart pointers is to keep track of object lifetime and ownership in a way that simply isn't possible in general with raw pointers, unless you hooked into the allocator and had some convoluted relationship between this allocator and any handles pertaining to the allocated object.
The benefits you are describing are the benefits that come neatly from using said extant smart pointers. shared_ptr and weak_ptr are perfect here.
There's no problem with locking (you want this) and there's no problem with there having to be a shared_ptr somewhere, because surely someone somewhere does own that data. If they don't, your design has much bigger problems and you're trying to hack around those problems with a similarly broken smart pointer concept that'll never exist in the standard.
I am somewhat new to the smart pointer world of C++ 11. I have been doing memory management manually and decided to dive into smart pointers. However, there is somewhat of a confusion though when it comes to managers
I define a manager as
An object that owns and manages a set of objects. The objects are exclusively owned by the manager and it's the manager's responsibly to control their life cycle (ie. delete them). It dispenses the objects for use in other parts of the program, but does not give away ownership.
In other words, it lets other parts of the program borrow the resources it manages.
What I am a little bit confused about, is how to ensure ownership is preserved by the manager?
For instance, in a videogame, a 'Sprite' might request a 'Texture' from a texture manager. The sprite doesn't own the texture, it simply wants to use it. One way to do this, is to utilize a list of unique_ptrs. So I have:
std::list<std::unique_ptr<SpriteTexture>> _spriteTextureList;
This however doesn't work, because I cannot establish a weak_ptr to a unique_ptr. On the other hand, I can create a list of shared_pointers
std::list<std::shared_ptr<SpriteTexture>> _spriteTextureList;
This will allow me to dispense weak_ptr to other parts of the program. However, the issue is that a shared_pointer can be duplicated, breaking ownership apart to multiple pointers. This of course can be controlled if I never pass back a shared pointer, but doing this seems to be counter-intuitive for what a shared_ptr is meant to represent.
The third alternative would be to simply dispense shared_ptr. However, this is not useful because then the manager doesn't technically own the objects. If the manager removes a Texture out of it's list and something else has a shared_ptr to the Texture, then the texture wont be deleted.
In the ideal situation this should be just fine, because there should be no existing pointers to the Texture before the manager deletes it, but I can see this becoming a debugging hassle.
I definitely have a weak understanding of smart pointers. Maybe I am miss understanding how smart pointers are supposed to be implemented?
Any help is greatly appreciated!
If "it simply wants to use it", then SpriteTexture* is just fine. Normal pointers are fine, as long as they don't have ownership semantics associated with them.
Just use your first solution (std::unique_ptr) and dispense normal pointers obtained with get().
You just have to make sure there are no other parts of the code using such a pointer when the manager decides to get rid of the associated object, but that's the opposite problem to the one in your question. (You sort of implied this wouldn't be a problem in your application.)
A side note: I can't think of a reason to use a std::list to hold those smart pointers. I think std::vector should be your first choice, unless you have a specific reason not to use it here.
More and more I hear, that I should use smart pointers instead of naked pointers, despite I have effective memory leak system implemented.
What is the correct programming approach on using smart pointers please? Should they really be used, even if I check memory leaks on allocated memory blocks? Is it still up to me? If I do not use them, can this be considered as programming weakness?
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
You should use RAII to handle all resource allocations.
Smart pointers are just one common special case of that rule.
And smart pointers are more than just shared_ptr. There are different smart pointers with different ownership semantics. Use the one that suits your needs. (The main ones are scoped_ptr, shared_ptr, weak_ptr and auto_ptr/unique_ptr (prefer the latter where available). Depending on your compiler, they may be available in the standard library, as part of TR1, or not at all, in which case you can get them through the Boost libraries.
And yes, you should absolutely use these. It costs you nothing (if done correctly, you lose zero performance), and it gains you a lot (memory and other resources are automatically freed, and you don't have to remember to handle it manually, and your code using the resource gets shorter and more concise)
Note that not every pointer usage represents some kind of resource ownership, and so not all raw pointer usage is wrong. If you simply need to point to an object owned by someone else, a raw pointer is perfectly suitable. But if you own the object, then you should take proper ownership of it, either by giving the class itself RAII semantics, or by wrapping it in a smart pointer.
You can't just blindly substitute std::auto_ptr for every raw pointer. In particular, auto_ptr transfers ownership on assignment, which is great for some purposes but definitely not for others.
There is a real reason there are several varieties of smart pointers (e.g., shared_ptr, weak_ptr, auto_ptr/unique_ptr, etc.) Each fulfills a different purpose. One major weakness of a "raw" pointer is that it has so many different uses (and has that versatility largely because it does little or nothing to assist in any one purpose). Smart pointers tend to be more specialized, which means they can be more intelligent about doing one thing well, but also means you have to pick the right one for the job or it'll end up dong the wrong things entirely.
Smart pointers allows to define automatically the life-time of objects it refers to. That's the main thing to understand.
So, no, you shouldn't use smart pointers everywhere, only when you want to automate life-time of your objects instead of having, for example, an object managing those objects inside from birth to death. It's like any tool : it solves specific kind of problems, not all problems.
For each object, you should think about the life cycle it will go through, then choose one of the simplest correct and efficient solution. Sometimes it will be shared_ptr because you want the object to be used by several components and to be automatically destroyed once not used anymore. Sometimes you need the object only in the current scope/parent-object, so scoped_ptr might be more appropriate. Sometimes you need only one owner of the instance, so unique_ptr is appropriate. Maybe you'll find cases where you know an algorithm that might define/automate the lifetime of an object, so you'll write your own smart pointer for it.
For example of opposite case, using pools forbids you to use smart_ptr. Naked pointers might be a more welcome simple and efficient solution in this particular (but common in embedded software) case.
See this answer (from me) for more explainations : https://softwareengineering.stackexchange.com/questions/57581/in-c-is-it-a-reflection-of-poor-software-design-if-objects-are-deleted-manuall/57611#57611
Should they really be used, even if I check memory leaks on allocated memory blocks?
YES
The whole purpose of smart pointers is, it help you implement RAII(SBRM), which basically lets the resource itself take the responsibility of its deallocation and the resource doesn't have to rely on you explicitly remembering to deallocate it.
If I do not use them, can this be considered as programming weakness?
NO,
It is not a weakness but a inconvenience or unnecessary hassle to explicitly manage the resources by yourself if you are not using Smart pointers(RAII). The purpose of smart pointers to implement RAII is to provide efficient and hassle free way of handling resources and you would just not be making use of it if you are not using it. It is highly recommended to use it purely for the numerous advantages it provides.
If the smart pointers(ex: std::auto_ptr)are strongly recommended, should I use them instead of every naked pointer?
YES
You should use smart pointers wherever possible because simply there is no drawback of using them and just numerous advantages to use them.
Don't use auto_ptr though because it is already deprecated!! There are various other smart pointers available that you can use depending on the requirement. You can refer the link above to know more about them.
It's a tricky question, and the fact that there is currently a mode to
use smart pointers everywhere doesn't make things any easier. Smart
pointers can help in certain situations, but you certainly can't just
use them everywhere, without thinking. There are many different types
of smart pointers, and you have to think about which one is appropriate
in every case; and even then, most of your pointers (at least in typical
applications in the domains I've worked in) should be raw pointers.
Regardless of the approach, several points are worth mentionning:
Don't use dynamic allocation unless you have to. In many
applications, the only things that need to be allocated dynamically
are objects with specific lifetimes, determined by the application
logic. Don't use dynamic allocation for objects with value semantics.
With regards to entity object, those which model something in the
application domain: these should be created and destructed according
to the program logic. Irregardless of whether there are pointers to
them or not. If their destruction causes a problem, then you have an
error in your program logic somewhere (not handling an event correctly,
etc.), and using smart pointers won't change anything.
A typical example of an entity object might be client connection in a
server, is created when the client connects, and destructed when the
client disconnects. In many such cases, the most appropriate management
will be a delete this, since it is the connection which will receive
the disconnection event. (Objects which hold pointers to such an object
will have to register with it, in order to be informed of its
destruction. But such pointers are purely for navigation, and shouldn't
be smart pointers.)
What you'll usually find when people try to use smart pointers
everywhere is that memory leaks; typical reference counters don't
handle cycles, and of course, typical applications are full of cycles: a
Connection will point to the Client which is connected to it, and
the Client will contain a list of Connection where it is connected.
And if the smart pointer is boost::shared_ptr, there's also a definite
risk of dangling pointers: it's far to easy to create two
boost::shared_ptr to the same address (which results in two counters
for the references).
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
In my opinion, yes, you should it for every pointer that you own.
Here are my ideas on resource management in C++ (feel free to disagree):
Good resource management requires thinking in terms of ownership.
Resources should be managed managed by objects (RAII).
Usually single ownership is preferred over shared ownership.
Ideally the creator is also the owner of the object. (However, there are situations where ownership transfer is in order.)
This leads to the following practices:
Make boost::scoped_ptr the default choice for local and member variables. Do keep in mind that using scoped_ptr for member variables will make your class non-copyable. If you don't want this see next point.
Use boost::shared_ptr for containers or to enable shared ownership:
// Container of MyClass* pointers:
typedef boost::shared_ptr<MyClass> MyClassPtr;
std::vector<MyClassPtr> vec;
The std::auto_ptr (C++03) can be used for ownership transfer. For example as the return value of factory or clone methods:
// Factory method returns auto_ptr
std::auto_ptr<Button> button = Button::Create(...);
// Clone method returns auto_ptr
std::auto_ptr<MyClass> copy = obj->clone();
// Use release() to transfer the ownership to a scoped_ptr or shared_ptr
boost::scoped_ptr<MyClass> copy(obj->clone().release());
If you need to store a pointer that you don't own then you can use a raw pointer:
this->parent = inParentObject;
In certain situations a boost::weak_pointer is required. See the documentation for more information.
In general you should prefer smart pointers, but there are a couple of exceptions.
If you need to recast a pointer, for example to provide a const version, that becomes nearly impossible with smart pointers.
Smart pointers are used to control object lifetime. Often when you are passing a pointer to a function, the function will not affect the lifetime; the function does not try to delete the object, and it does not store a copy of the pointer. The calling code cannot delete the object until the function returns. In that case a dumb pointer is perfectly acceptable.
Yes. Assuming you have C++0x available to you, use unique_ptr or shared_ptr (as appropriate) to wrap all the raw pointers you new up. With the help of make_shared, shared_ptr is highly performant. If you don't need reference counting then unique_ptr will get you better perf. Both of them behave properly in collections and other circumstances where auto_ptr was a dumb pointer.
Using smart pointers (shared_ptr or otherwise) EVERYWHERE is a bad idea. It's good to use shared_ptr to manage the lifetime of objects/resources but it's not a good idea to pass them as parameters to functions etc. That increases the likelihood of circular references and other extremely hard to track bugs (Personal experience: Try figuring out who should not be holding onto a resource in 2 millions lines of code if every function invocation changes the reference count - you will end up thinking the guys who do this kind of thing are m***ns). Better to pass a raw pointer or a reference.
The situation is even worse when combined with lazy instantiation.
I would suggest that developers should know the lifecycle of the objects they write and use shared_ptr to control that (RAII) but not extend shared_ptr use beyond that.
I'm creating a gui api for games. I have for example a font for each widget in the form of a Font* . Right now I have it so that I do not ever manage the memory of these (for obvious reasons) because I think the user can use smart pointers if they want this memory managed. The con to this is that it is not very idiot proof. If a user set the font like this:
obj.setFont(new Font(""));
This would immediately cause a memory leak because no one ever frees it. The only way would be to delete getFont();
Would it be instead better for me to manage these?
Thanks
It's your decision if your library should take ownership of the resource, but whatever you choose, make it clear through the interface (and not only through comments or documentation).
In C++03, a good way to make it explicit that you are actually taking ownership is to receive the parameter as a std::auto_ptr : the client will have no doubt that he's transferring ownership
On the opposite, receiving a parameter through const reference should make it clear that you have no intention to ever delete the data (you can't possibly know if it has actually been new'ed in the first place).
Anyway, going for smart pointers would probably help with these questions.
It should be the responsibility of the caller to manage the memory of objects that are within the caller's scope.
That being said, in this case, you should really use smart pointers because they will deallocate themselves when they are no longer of use.
That's the problem with transferred ownership.
But: You can rewrite your interface to
void obj.setFont( SmartPtr<Font> font );
because then you are forcing the user to use a smart pointer.
I have a C++ application which makes extensively use of pointers to maintain quite complex data structures. The application performs mathematical simulations on huge data sets (which could take several GB of memory), and is compiled using Microsoft's Visual Studio 2010.
I am now reworking an important part of the application. To reduce errors (dangling pointers, memory leaks, ...) I would want to start using smart pointers. Sacrificing memory or performance is acceptible as long as it is limited.
In practice most of the classes are maintained in big pools (one pool per class) and although the classes can refer to each other, you could consider the pool as owner of all the instances of that class. However, if the pool decides to delete an instance, I don't want any of the other classes that still refers to the deleted instance to have a dangling pointer.
In another part I keep a collection of pointers to instances that are delivered by other modules in the application. In practice the other modules maintain ownership of the passed instance, but in some cases, modules don't want to take care of the ownership and just want to pass the instance to the collection, telling it "it's yours now, manage it".
What is the best way to start introducing smart pointers? Just replacing pointers [at random] with smart pointers doesn't seem a correct way, and probably doesn't deliver all the (or any of the) advantages of smart pointers. But what is a better method?
Which types of smart pointers should I further investigate? I sometimes use std::auto_ptr for the deallocation of locally allocated memory, but this seems to be deprected in C++0x. Is std::unique_ptr a better alternative? Or should I go straight to shared pointers or other types of smart pointers?
The question Replacing existing raw pointers with smart pointers seems similar but instead of asking how easy it is, I am asking what the best approach would be, and which kind of smart pointers are suited best.
Thanks in advance for your ideas and suggestions.
I recommend using unique_ptr when possible (this may require some program analysis) and shared_ptr when this is impossible. When in doubt, use a shared_ptr to maximize safety: when handing off control to a container, the reference count will simply go to two and then back to one and the container will eventually delete the associated object automatically. When performance becomes an issue, consider using boost::intrusive_ptr.
Here are the 3 varieties found in the new C++11 standard (unique_ptr replaces auto_ptr)
http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr
http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr
http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr
You can read the text for each pointer and there is an explanation of when to use which in there. For local memory management unique_ptr is the choice. It is non-copyable but movable so as you move it around the receiver takes ownership of it.
Shared_ptr is used if you want to share an object instance around with no one really owning the object and to make sure it doesn't get deleted while someone still has a reference to it. Once the last user of an object destroys the shared_ptr container, the contained object will be deleted.
weak_ptr is used in conjunction with shared_ptr. It enables one to "lock" to see if the reference shared_ptr object still exists before trying to access the internal object.