shared_ptr Initial Assignment

Hi, Say I have a class definition: class Foo() {...}; And an instance of that class: Foo fooInstance; I would like to create a shared_ptr pointing to this instance of Foo. Most documentation recommends the following way to do it: shared_ptr<Foo> bla(new Foo(fooInstance)); But can I also do this: shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance)); Are there any problems with the second (or the first) method? Thanks, Lex

Lex, Both shared_ptr<Foo> bla(new Foo(fooInstance)); And Shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance)); will end up with bla pointing to the new Foo. The second will create a temporary which will go away. Note that neither of these will end up with bla pointing to fooInstance, but only a copy of fooInstance created with the copy constructor onto the heap. If you really want bla to point to fooInstance then you need to use bla.reset(&fooInstance) BUT there are several condition that need to be satisfied or you have just set a time bomb in your program. 1st, fooInstance needs to be on the heap, and created by new. Your example code has fooInstance being a non-heap object, either on the stack if the declaration was in a function, or a global. This will lead to undefined behavior as soon as bla no longer points to fooInstance, or when bla goes out of scope, as the shared_ptr will try to delete something which was not new'ed 2nd, is fooInstance is on the heap, you need to be sure that no one else is going to delete fooInstance or you end up with a double delete. This is why the idiom is to stuff the pointer into the shared_ptr immediately, as that reduces the chances of letting the pointer get "owned" by multiple things. Richard Damon -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Lex Fridman Sent: Thursday, April 24, 2008 5:35 PM To: boost-users@lists.boost.org Subject: [Boost-users] shared_ptr Initial Assignment Hi, Say I have a class definition: class Foo() {...}; And an instance of that class: Foo fooInstance; I would like to create a shared_ptr pointing to this instance of Foo. Most documentation recommends the following way to do it: shared_ptr<Foo> bla(new Foo(fooInstance)); But can I also do this: shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance)); Are there any problems with the second (or the first) method? Thanks, Lex

Richard Damon [Richard@Damon-family.org] wrote:
Lex,
If you really want bla to point to fooInstance then you need to use
bla.reset(&fooInstance)
BUT there are several condition that need to be satisfied or you have just set a time bomb in your program.
1st, fooInstance needs to be on the heap, and created by new. Your example code has fooInstance being a non-heap object, either on the stack if the declaration was in a function, or a global. This will lead to undefined behavior as soon as bla no longer points to fooInstance, or when bla goes out of scope, as the shared_ptr will try to delete something which was not new'ed
I've had the op's situation myself. My solution to making a shared pointer reference a static object is to define a function called "NullDelete", then pass NullDelete as a second parameter to the shared pointer. This prevents the shared pointer from attempting to delete a statically allocated object. Do avoid letting a shared pointer reference a stack object, as you can have dangling shared pointers when the object goes out of scope. Sample code follows: void NullDelete (void const *) { //Intentionally blank } Option 1: static Foo static_foo1; boost::shared_ptr <Foo> bar1 (&static_foo1, &NullDelete); Option 2: static Foo static_foo2; boost::shared_ptr <Foo> bar2; Bar2 = boost::shared_ptr <Foo> (&static_foo2, &NullDelete); Option 1: static Foo static_foo3; boost::shared_ptr <Foo> bar3; Bar3.reset (&static_foo3, &NullDelete);

Hi Richard, That was foolish of me to think that bla will point to fooInstance. Obviously it will point to a copy of Foo instance. Thanks for that note. However, you also mentioned that the two options are different: (1) shared_ptr<Foo> bla(new Foo(fooInstance)); (2) shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance)); You mentioned that the second will create a temporary that will "go away". Can you elaborate on that. It seems to me that it shouldn't go away, as long as bla is within scope. I guess that was my main question originally, whether the second option is a correct way to set bla (when, say, it's a class member). Many thanks! Lex

Hi Lex! shared_ptr<Foo> bla; // Creates an empty shared_ptr object bla = shared_ptr<Foo>(new Foo(fooInstance)); // Creates a temporary shared_ptr object, // which owns the copy of fooInstance, // then assigns this temporary object to bla. // Now both bla and the temporary object own // the fooInstance-copy. ...; // Afterwards the temporary shared_ptr object // is not needed anymore and is deleted. // Now only bla owns the fooInstance-copy. // The exact moment, when the temporary object // is destroyed, depends on your compiler toolset. Regards, T. -----Ursprüngliche Nachricht----- Von: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] Im Auftrag von Lex Fridman Gesendet: Freitag, 25. April 2008 04:25 An: boost-users@lists.boost.org Betreff: Re: [Boost-users] shared_ptr Initial Assignment Hi Richard, That was foolish of me to think that bla will point to fooInstance. Obviously it will point to a copy of Foo instance. Thanks for that note. However, you also mentioned that the two options are different: (1) shared_ptr<Foo> bla(new Foo(fooInstance)); (2) shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance)); You mentioned that the second will create a temporary that will "go away". Can you elaborate on that. It seems to me that it shouldn't go away, as long as bla is within scope. I guess that was my main question originally, whether the second option is a correct way to set bla (when, say, it's a class member). Many thanks! Lex _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Lex,
However, you also mentioned that the two options are different: (1) shared_ptr<Foo> bla(new Foo(fooInstance));
(2) shared_ptr<Foo> bla; bla = shared_ptr<Foo>(new Foo(fooInstance));
You mentioned that the second will create a temporary that will "go away". Can you elaborate on that. It seems to me that it shouldn't go away, as long as bla is within scope. I guess that was my main question originally, whether the second option is a correct way to set bla (when, say, it's a class member).
Have a look at http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/shared_ptr.htm#BestPract... Regards, Rainer
participants (5)
-
Andrew Holden
-
Lex Fridman
-
Rainer Thaden
-
Richard Damon
-
Spam-Receiver