4

I have got:

boost::shared_ptr<Car> sptr;

Now I would like to assign an address from other object:

Car object;
sptr = &object;//error

As we can see in the comment there is an error. So my question is how can I assign an address from some object to shared_ptr? If it was normal a pointer the case would be simply:

Car *ptr;
Car object;
ptr = &object;//ok

How to use in this case boost::shared_ptr? Thanks

user1519221
  • 631
  • 5
  • 13
  • 24
  • If `boost` works anything like the `std`, you want to use `&(sptr.get())`. – Colin Basnett Sep 30 '13 at 22:13
  • 1
    http://stackoverflow.com/questions/8466459/create-a-boostshared-ptr-to-an-existing-variable – Nemanja Boric Sep 30 '13 at 22:13
  • 1
    *"As we can see in the comment there is an error."* Yes, there is an error, however, you didn't add the _actual error message_. Always copy those, as they might contain helpful information. In this case Dietmar's answer contains everything important, but your next question might be a little bit more complicated. – Zeta Sep 30 '13 at 22:27

2 Answers2

6

You could make the assignment work by explicitly converting your pointer to a boost::shared_ptr<Car>:

boost::shared_ptr<Car> sptr;
Car object;
sptr = boost::shared_ptr<Car>(&object);

However, that would be an extremely Bad Idea:

  1. When the last copy of sptr goes out of scope, Car would be deleted but it was never newed. Although you might be able to work around this problem by using a suitable deleter, i.e., one which doesn't do anything, this doesn't really help:
  2. Since object lives on the stack, it is destroyed when it goes out of scope, not when the last copy of sptr goes out of scope.

You should only manage objects on the heap with shared pointers. Stack allocated objects and objects embedded into other objects have their own life-time management.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • I noticed that both your and Linuxios answer use `= boost::shared_ptr<...>()`. Is there any particular reason for not using `shared_ptr<...>::reset(Y * ptr)`, apart from personal taste? – Zeta Sep 30 '13 at 22:19
  • 1
    @Zeta: `reset()` would work, too. Constructing the `boost::shared_ptr<...>()` would give the opportunity to also pass a deleter. However, it is essentially personal taste. – Dietmar Kühl Sep 30 '13 at 22:25
0

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 deleteing 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.

Tim
  • 8,912
  • 3
  • 39
  • 57