A raw pointer, e.g. Car*
, can point to another object, wherever it may be. It can be on the stack, or on the heap, it doesn't matter. The raw pointer does not 'own' the object -- ie. it will not clean up the object -- it simply says "the object is over there".
A smart pointer, e.g. shared_ptr<Car>
, tries to 'own' or 'manage' the object. The object must be allocated on the heap, and probably allocated with new
. When the shared_ptr goes out of scope, it cleans up the Car by delete
ing it. Thus, a shared_ptr must only hold a heap-allocated object.
I.e.:
Car foo; // stack allocated
Car* p = &foo; // points to the stack-allocated Car foo.
shared_ptr<Car> sp (new Car); // heap-allocates a Car, and holds it in a smart ptr.
p = sp.get(); // p points to the heap-allocated Car held by sp.
shared_ptr<Car> sp2 (&foo); // BAD. it will compile, and die at runtime.
Side note:
shared_ptr allows multiple shared_ptrs to point to the same object, and won't clean it up until all of the shared_ptrs are gone.
The bad shared_ptr usage will die when it goes out of scope and tries to delete the stack-allocated Car. This can give you misleading stack traces, and be difficult to debug.