What makes smartpointers better than normal pointers?
They simplify the problem of resource management. Once you hold your resources within smart pointers they will release memory for you when they go out of scope applying RAII techniques.
This has two main advantages: code is safer (less prone to resource leaks) and programming is easier as you do not need to remember in each part of your code whether the resource you are holding must be manually released.
The principal advantage is that the memory pointed to by the smart pointer will be automatically deallocated when the pointer does out of scope. With regular pointers, you have to manage the memory yourself.
A raw pointer doesn't take ownership of the resource it points to. When the pointer goes out of scope, the object it pointed to is unaffected. Often, you want some kind of ownership semantics where, when the pointer goes out of scope, the object it points to should either be deleted, or at least be notified that there's one less pointer pointing to it.
That is what smart pointers do.
A shared_ptr implements reference-counting, so that when all pointers to an object are destroyed, the object gets deleted.
Others, like scoped_ptr or unique_ptr or auto_ptr implement various forms of exclusive ownership. When a scoped_ptr is destroyed, it deletes the object it points to.
Fewer memory leaks. Maybe Scott Meyers can make it clearer for you:
Effective C++
More Effective C++
Automatic reference counting and deallocation.
While agreeing with the other answers in practice, I'd just like to say that nothing makes smart pointers better in principle, unless they happen to be what works for your application. That is, if a smart pointer isn't needed, it isn't better.
If the smart pointer you're talking about is std::auto_ptr, it could well be substantially worse than a simple pointer. But that's not so much a smart pointers issue as a semantics of assignment issue.
That said, smart pointers very often are useful - even the dreaded auto_ptr - especially (as mentioned above) WRT exception safety.
Have a look at:
Smart Pointers
Related
I know, that std::shared_ptr uses reference counting, so it has copy&move semantics, on the other hand std::unique_ptr (hence the name unique) only has move semantics, so trying to copy it is a compile error.
However, its not quite clear for me how big of a deal is that. Can I simply use std::shared_ptr over std::unique_ptr in most cases, or should I use std::unique_ptr whenever possible, as it's far more efficient because it doesn't have to take care of reference counting?
Also, I know that smart pointers are useful when dealing with, for example exception safety, but are they a mean to generally replace traditional T* pointers?
Is it a good programming practice to use smart pointers over traditional T* pointers whenever possible?
The rule of thumb is:
If you can, use a stack based object directly or by a reference instead of using pointers.
Else, if you don't have to deal with shared ownership (usually you don't) use unique_ptr - it is not only faster, but also safer (no circular references).
Else, if you do have shared ownership, use shared_ptr
Raw pointers are OK in certain circumstances when they don't carry ownership - for instance as an input argument to a function:
void draw (const shape* sh) {
sh->draw();
}
...
std::unique_ptr<shape> ptr(new triangle);
draw(ptr.get());
The problem with the shared_ptr is, that, afaik, the reference counting is an atomic function, that means it not only counts the references, but also has locking functionality to ensure that the function is atomic. So at that point, yes, unique_ptr is better to use, when you only need move functionality.
Personally, I dont use shared_ptr alot, mostly normal pointers are enough. Imho smart pointers are only encourage getting lazy in memory management. I was in projects where smart pointers only caused race conditions when quitting the program, because nobody knew the order of destruction and these pointers referenced each others. For myself, I only use them if a lib of mine is putting pointers to the outside for which it is irrelevent when they get deleted (or in which order).
You should prefer values to std::unique_ptr, and std::unique_ptr to std::shared_ptr whenever possible, but not for performance reasons. Yes, there is some overhead when it comes to std::shared_ptr, as they use inside some form of atomic counter, but this is negligible for most applications.
The main reason to use std::unique_ptr is the uniqueness semantics - when you (or someone else) read(s) the code it's very clear the lifetime and the ownership of the object. This makes it more easy to reason about the code and find logical/performance issues.
PS: std::unique_ptr has no overhead compared to raw pointer, but it has some great advantages.
A shared_ptr has the extra cost of construction/destruction of the pointer itself, if passed to a function, plus the reference counting mechanism.
Do not listen to anyone that says either smart pointers are always the way to go, nor to people who say raw pointers are always better.
There are cases where smart pointers make sense, and cases where raw pointers are preferable.
For a more detailed and comprehensive read, I'll suggest you to visit:
http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
It covers all the points you raised and it is an easy read for the most part.
shared_ptr means that the ownership rules surrounding the resource are complicated. Understanding them requires tracking down the lifetime of all shared_ptrs in the general case.
unique_ptr means that the ownership rules surrounding the resource are dead easy.
Both enforce a set of ownership rules, but the rules for unique_ptr are simple and local, the rules for shared_ptr are complex and non-local. If you are in a situation where you are choosing between the two casually, then you aren't treating lifetime issues with the gravity they deserve.
If you have a pointer-like resource whose lifetime should be controlled simply, or even at some central location (type-wise) with complex logic around it, use unique_ptr. The cost over a raw pointer is minimal, and it adds (enforced) documentation that this is the "owning" pointer to this resource.
If you must have a resource whose lifetime is the union of the lifetime of a bunch of other objects, all of whom have unrelated lifetimes, shared_ptr can be considered. If your situation is so complex that a loop could possibly be formed, then naive shared_ptr use is no longer a practical option.
shared_ptr and weak_ptr can also be used as a distributed lifetime notification system, where a central location stores a (mostly unique) shared_ptr, and clients store weak_ptrs. Local (non-stored) shared_ptrs are created from the weak_ptrs in order to check that the target resource still exists, then the resource is manipulated, then the local shared_ptr is discarded. The goal here is to make (in a non-language enforced way) a unique_ptr with weak shares, so reasoning about lifetime is only marginally harder than the unique_ptr case.
shared_ptr basically never "solves" the lifetime problem without you proving that it will solve your lifetime problems. It can make some parts of that proof marginally easier.
I have some questions about smart pointers implemented in boost library.
Is the only diffrence between shared_ptr and scoped_ptr that scoped_ptr doesn't have copy constructor and shared_ptr has it?
Should i use then scoped_ptr instead of shared_ptr always when object doesn't call copy constructor?
I also doesn't understand idea of shared/scoped array. Can't I just use std::vector instead of it?
Is the only diffrence between shared_ptr and scoped_ptr that
scoped_ptr doesn't have copy constructor and shared_ptr has it?
The difference is more fundamental than that; it has to do with how the smart pointers own the object it points to. What makes smart pointers different from dumb pointers is that the concept of ownership is a core component of their function. The ownership semantics is what differentiates the different kinds of smart pointers.
Because smart pointers "own" the thing they point to, they can do useful things like deleting objects when the smart pointers go away (this is made possible using only the rules of the language; no compiler magic is needed). This way, memory management can be made almost automatic in C++ (despite claims to the contrary, there's very little manual memory management required in modern C++).
shared_ptr implements reference-counting
semantics for
memory management. Multiple shared_ptrs can own a single object. A
shared_ptr going away does not necessarily delete the object it
points to because there may be another shared_ptr owning the
object. The last shared_ptr that owns an object and goes away will
delete the object it owns.
scoped_ptr implements exclusive-ownership semantics. Only one
scoped_ptr can own any one object. When a scoped_ptr goes away,
it will always delete the object it owns (because there's only one
owner). It's typically used as a lightweight RAII mechanism for
objects allocated on the free store.
The array versions (shared_array and scoped_array) have essentially the same semantics, but are designed specifically for arrays e.g. they use delete[] instead of delete, implements the array subscript operator, etc.
shared_ptr and shared_array also allows you to specify a custom deleter, if the default delete behavior is not appropriate for the object. scoped_ptr and scoped_array do not have that ability, since they are quite lightweight compared to shared_ptr and shared_array.
In C++11, the newest and current version of C++, there's also a unique_ptr, which is just like scoped_ptr except that you can transfer the ownership of an object to another unique_ptr. In C++03, an older but more widely supported version of C++, there's auto_ptr which is equivalent to unique_ptr except it was easy to use it in an unsafe manner by accident (which is why it is deprecated in C++11).
Should i use then scoped_ptr instead of shared_ptr always when object
doesn't call copy constructor?
Which one you choose doesn't depend on the presence of the copy-constructor, since shared_ptr and scoped_ptr does not require the object to be copy-constructible. You pick the one depending on the required ownership semantics. If the object will have multiple owners, you use shared_ptr. If the object will only have one owner and the object's existence lasts only within a scope, use scoped_ptr (hence the name scoped_ptr).
I also doesn't understand idea of shared/scoped array. Can't I just
use std::vector instead of it?
std::vector does not implement reference-counting semantics like shared_array does. std::vector is more like scoped_array, but can be copied. When you copy a std::vector, you also copy all of the elements it contains. That's not the case for scoped_array. std::vector also has functions that allow you to manipulate and examine its contents (e.g. push_back, insert, erase, etc.), but is much more heavyweight than scoped_array.
Yes. scoped_ptr does not allow for copies while shared_ptr does. But this "simple" difference makes a world of impact on both the implementation and the usage of the smart pointer.
scoped_ptr is faster and lighter than shared_ptr because no reference counting is involved. shared_ptr will count the number of assignments and not delete the object until all references have expired/gone out of scope.
Now your question regarding vectors implies that you're actually not familiar with the the concept of dynamic allocation and the difference between that and static allocation on the static. You really should look into reading a primer on C(++) and look into the reasons for dynamic allocation and when you need it.
A vector stores a list of objects. A XXX_ptr stores a pointer to a (single) dynamically-allocated object. Apples and oranges.
If you allocate memory, you can put the newly created pointer in a scoped pointer, so that IF the malloc/noew fails, the memory will be freed. This is how I usally uses it, or if it's an object that needs to be allocated on the heap, but that I want to treat it as a stack object in terms of that it will only be alive until the end of the scope.
The shared pointer is if you want to pass the pointer around and allow the object to have multiple owners. Then none of the owners needs to take responibility of the object and they can all just stop using it and be sure that it will be freed correclty. (you don't wanna free an object that you know is used by someone else)
I'd say you're thinking about it the wrong way. The question isn't whether you do call the copy constructor -- it's whether you need to call the copy constructor. In other words, you should be deciding whether to use shared_ptr or scoped_ptr not based on reading your code but based on thinking about object ownership and what objects' lifetimes should be.
Say you have an object that you want to create on the heap, not on the stack, for whatever reason (maybe it's too big to be on the stack, maybe you might want to replace it with a different object at some point, maybe you want it to be initialized late) but its lifetime should never be longer than its containing scope. A common example of this is instance variables in a class: they should often be deleted when the object they are in is deleted. Then, you should use scoped_ptr.
But sometimes you don't know when an object will be safe to delete in advance. For instance, consider an object in a lookup table. You want to return it in response to lookups, but what happens when it's deleted -- could someone still be using the object who looked it up previously? In cases like this, you can use shared_ptr, which shares the objects ownership so that it only gets deleted when nobody has a copy of the pointer anymore.
So why does anyone ever use scoped_ptr instead of shared_ptr? First of all, knowing when the destructor gets called is one of the big advantages of non-memory-managed languages like C++. Maybe the destructor is expensive, or maybe it frees a resource; it's nice to know when these things happen. Also, with shared_ptr, there's the potential for memory leaks if you create a circular reference by accident.
In general, almost every pointer you have should be "owned" -- there should be a single place in your code that news and deletes it. scoped_ptr is great for this; when you want an owned object to be passed around to non-owners you can use a bare pointer. But if you absolutely need an object's ownership to be shared, use shared_ptr -- as long as you're careful to use it correctly!
As for scoped/shared arrays, you can certainly use std::vector, but arrays are cheaper and sometimes people want the performance benefit.
shared_ptr is very different from scoped_ptr. scoped_ptr (which is now standardized in C++11 as std::unique_ptr) is simply a RAII-style smart pointer which takes ownership of a resource and then deallocates the owned resource when the pointer goes out of scope.
A shared_ptr however, may share ownership of the resource with other instances of shared_ptr. The resource stays alive as long as one or more shared_ptr instances own it. This is an automatic memory-management technique, (a form of garbage-collection) known as reference counting. It basically provides the same effect as more advanced garbage collection algorithms, except unlike other garbage collection techniques, it doesn't handle circular references.
As for using std::vector versus boost::scoped_array, yeah - scoped_array doesn't really offer much of an advantage. However, boost::shared_array offers reference counting semantics, just like shared_ptr.
Based on this
Stroustrup suggests that "A pointer in a function should not represent ownership"
Question> Can someone give me a little detail explanation? Best if an example is illustrated.
Thank you
A pointer is "owned" by some code if that code is responsible for deleting it, or for transferring ownership to someone else. Various smart pointers implement explicit ownership models. shared_ptr represents multiple pieces of code owning a pointer. unique_ptr represents only one piece of code that owns the pointer.
What he's saying is that if a function has a naked pointer (a pointer not in a smart pointer), it should not be considered to own it. If it is to claim some ownership of this pointer, it should either have been given a smart pointer as a parameter, or it should have stored the pointer it created with new in a smart pointer.
He's saying that only smart pointers own pointers. If a function takes a naked pointer as a parameter, it does not claim ownership of that pointer. If a function returns a naked pointer, you cannot claim ownership of that pointer.
std::unique_ptr<int> pOwner(new int(5)); // this is the owner
int* pAccess = pOwner.get(); // this is a weak accessor, it does not own anything
He's talking about the role of raw pointers in a C++11 world. Owning pointers are meant to be shared_ptr and unique_ptr (they are the owners because they are responsible for deleting the object). Raw pointers should be used to access objects which are owned by a smart pointer. In C++11 you should basically never have a reason to explicitly call delete on a raw pointer anymore.
When you create a dynamic object using new, some other object will be responsible for deleting it once it is no longer needed; that object is the dynamic object's "owner".
If you were to always refer to the object using plain pointers, then it's difficult to tell (without documentation) which of those pointers pointers represents ownership. If you pass a pointer to a function, then does the function take ownership? Or is the caller still responsible for deleting it? If you get that wrong, then you'll either not delete it (causing a resource leak, which might degrade your program's performance and eventually stop it from working), or you might delete it too soon (which can cause all manner of bugs, often very hard to track down).
A widely-used solution for this is to have a policy of always using smart pointers (objects that look like pointers, but contain logic to manage their target's lifetime) to denote ownership, and to never delete anything to which you just have a plain pointer. Then there is never any confusion about whether or not to delete something. The standard library provides smart pointers (unique_ptr and shared_ptr) that give the common semantics of ownership by a single object, and ownership shared between multiple objects.
This is one aspect of the wider topic of resource management via RAII, which is extremely important in C++. As well as providing a clear ownership model, it is also the only sensible way to reliably prevent memory leaks when exceptions are thrown.
I have a project and I want make smart pointers usage better.
The main idea is to use them when returning new object from function. The question is what smart pointer to use? auto_ptr or shared_ptr from boost? As I know, auto_ptr is slower but it can fall back to the 'pure' pointer.
And if I'll use smart pointer in place where I don't need it, would it make the perfomance slower?
What makes you think auto_ptr is slower than shared_ptr? Typically I would expect the reverse to be true, since shared_ptr needs to update the reference count.
As for which you should use, different smart pointers imply different ownership semantics. Ownership implies the responsibility to delete the object when it is no longer needed.
A raw pointer implies no ownership; a program that uses smart pointers correctly may still make use of raw pointers in a lot of places where ownership is not intended (for example, if you need to pass an optional reference to an object into a function, you would often use a raw pointer).
scoped_ptr implies single (ie, non-shared), non-transferable ownership.
auto_ptr implies single (ie, non-shared) transferable ownership. This is the smart pointer I would use to return a newly constructed object from a function (the function is transferring the object to its caller). auto_ptr suffers from the disadvantage that due to limitations of the language when auto_ptr was defined, it is difficult to use correctly (this has given it a very bad reputation, though the intended purpose of a smart pointer with single, transferable ownership semantics was and is both valid and useful).
unique_ptr has the same semantics as auto_ptr, but uses new C++0x features (rvalue references) to make it a lot safer (less prone to incorrect use) than auto_ptr. If you are developing on a platform where unique_ptr is available, then you should use it instead of auto_ptr.
shared_ptr implies shared ownership. In my opinion this is over-used. It does have many valid uses, but it should not simply be used as a default option.
I would also add that shared_ptr is often used with STL containers because the other smart pointer classes do not achieve their intended function in that context (due to copying of values internally within the container). This often leads to use of shared_ptr where shared ownership is not really the intended meaning. In these cases, I suggest (where possible) using the boost pointer-container classes (ptr_vector, ptr_map and so on), which provide the (commonly desired) semantics of a container with transferable, but single (non-shared) ownership.
You should always think about the ownership of your objects: in most cases, with a clean system design, each object has one obvious owner, and ownership does not need to be shared. This has the advantage that it is easy to see exactly where and when objects will be freed, and no reference counting overhead is needed.
[edited to note the new unique_ptr]
You probably should use shared_ptr<>. It's hard to be more specific without knowing what exactly you want to do. Best read its documentation and see if it does what you need.
The performance difference will most likely be negligible. Only in extreme cases there might me an noticeable impact, like when copying these pointers many million times each second.
I prefer shared_ptr, auto_ptr can cause a lot of trouble and its use is not too intuitive. If you expect this object to be inserted on a STL container, so you certainly want to use shared_ptr.
Abot the performance you have a cost, but this is minimal and you can ignore it most of the time.
Depends.
Shared pointers have a better use than auto_ptr which have the unusual characteristic of changing ownership on assignments.
Also auto_ptr can not be used in containers.
Also you can not use auto_ptr as return values if you do not want to transfer ownership.
Shared pointers have all the benefits of smart pointers, have overloaded the relevant operators to act like a pointer and can be used in containers.
Having said that, they are not cheap to use.
You must analyze your needs to decide if you actually gain something by avoiding the shared_pointer implementation overheads
Use only shared_ptr. With auto_ptr you can have ONLY ONE reference to your object. Also auto_ptr isn't slower it must work faster than shared_ptr.
To not ask such questions you need to know, how this smart pointers work.
auto_ptr just storing pointer to your object and destroying it in it's destructor.
The problem of auto_ptr is that when you are trying to copy it it's stopping to point to your object.
For example
auto_ptr a_ptr(new someClass);
auto_ptr another_ptr=aptr;// after this another_ptr is pointing to your class, but a_ptr isn't pointing to it anymore!
This is why I don't recomend you to use auto_ptr.
Shared pointer counting how much smart pointers are pointing to your object and destroying your object when there is no more pointers to it. That's why you can have more than 1 pointer pointing to your object.
But Shared pointer also isn't perfect. And if in your program you have cyclic graph (when you have classes A and B and A have a member shared_ptr wich points to B and B have or B's member objects have shared_ptr pointing to A) than A and B will never deleted and you will have memory lick.
To write correct code with shared_ptr you need to be careful and also use weak_ptr.
For more information look at here http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/smart_ptr.htm
I've been using C++ for a long time and know very well about carefulness in allocating and deallocating memory, especially not forgetting to delete unused instances.
Now, I've just recently used boost and with a problem I am facing I'm forced to used smart pointers (specifically the shared_ptr) one. So, if I am going to use shared_ptr for this problem, should I use smart pointers to all my normal pointer codebase?
You should use smart pointers careful. They are not the silver bullet when considering memory management. Circular references are still an issue.
When making the class design, always think who has the ownership of an object (has the responsibility to destroy that object). Complement that with smart pointers, if necessary, but don't forget about the ownership.
Yes, you should greatly prefer smart pointers over bare pointers for almost everything. But that does not mean you should be using ::boost::shared_ptr for most of those cases. In fact I think you should use shared_ptr sparingly and carefully.
But for those pointers you don't use shared_ptr for you should be using ::std::auto_ptr or, if you have C++0x ::std::unique_ptr. And if they aren't appropriate, you should find a smart pointer type that is.
Now this isn't always the right answer, just almost always. Smart pointers are invaluable for tracking and freeing memory resources appropriately even in the face of exceptions or other such oddities of control flow.
There are cases in which you will need to either write your own smart pointer class or not use one. These cases are very rare, but they exist.
For example, using a smart pointer in your own smart pointer class is probably not the right thing to be doing. Pointing at stuff allocated in a C library would probable require a custom smart pointer that called free instead of delete. Maybe you want a stretchy buffer you can call realloc on and don't want to use a ::std::vector for some reason.
But generally, a smart pointer (though not usually ::boost::shared_ptr (or in C++0x ::std::shared_ptr)) is the right answer to your resource management problem.
Yes. You should be using the Boost smart pointers for most everything if you have them available. Remember this, while you can and from your comments do use pointers effectively, the person/people that come after you may not. Using the smart pointers can and will (hopefully, can't guard against bad code) mitigate some of these issues.
I'd also recommend using scoped_ptr inside your classes even if your classes are designed well. It'll help guard against issues the next guy could/might/most likely will introduce when faced with a naked pointer. It'll encourage them to use them too, by example. The last thing you want is to have to track down a memory issue because someone forgot to initialize the pointer to NULL and it's passing the if statement check.
No, you should not use smart pointers for everything.
What you should consider whenever typing new:
What is the lifetime of this object?
Which object owns it?
How is that object going to manage its lifetime?
Sometimes the solution is a smart pointer but also the lazy answer. "I don't want to be bothered to work out which object owns this pointer and what its lifetime should be hence I'll make it a shared_pointer!"
The important question is; What is managing the lifetime of this object?, the answer can be a smart pointer, but oftentimes, it doesn't need to be.
No. It depends on what you're doing.
Smart pointers have a performance overhead. In desktop applications, this is typically not a concern, but depending on what you do, it might be.
Smart pointers will not work right if you have reference cycles, i.e. A pointing to B and B pointing to A, or even something pointing to itself.