Problem with "this" and shared_ptr

Hello, given the following code which uses shared_ptrs, I'm getting a double-free onto an object of type A: ------------------------------------------------------ #include <boost/shared_ptr.hpp> #include <list> #include <iostream> class A { public: A(void){} void makeSomething(void); void makeSomethingOther(void) { std::cout << "A" << std::endl; } }; typedef boost::shared_ptr<A> APtr; class B { public: B(const APtr& a) : mA(a) {} void makeSomething(void) { std::cout << "B" << std::endl; mA->makeSomethingOther(); } private: APtr mA; }; void A::makeSomething(void) { B b(this); // here I want to hand over the "A" shared pointer to "B", but I have only my "this" at hand. std::cout << "A" << std::endl; b.makeSomething(); } int main(void) { APtr a(new A); a->makeSomething(); } ------------------------------------------------------ (please don't ask me about why I'm doing it in that way, the code is stripped down from a much bigger program) I understand that the problem results from the accesss to "this" in the commented line. Is there an elegant way to get the shared_ptr pointing to "this" from "this", which would be the solution to the fault? Or do I have to store a shared_ptr member variable referencing "this" in the class A which is set by a A::method from outside of A to reference it? (not very beautiful) Sorry if this is a FAQ, but I didn't find a solution on news.gmane.org kind regards Michael

On Tuesday, December 17, 2002, at 06:44 AM, Michael Brinkmann wrote:
Is there an elegant way to get the shared_ptr pointing to "this" from "this", which would be the solution to the fault?
Yes. There is a relatively new feature in the latest versions of shared_ptr, shared_from_this. The way you use it in Boost 1.29.0 is to the class you want to store a pointer to inherit from boost::counted_base. You can use multiple inheritance if you already have another base class. Then you can use shared_from_this to turn a raw pointer to this class into a shared_ptr. I expect this feature is going to be in future versions of shared_ptr, but the name of the class you have to inherit from may change. -- Darin

On Tue, Dec 17, 2002 at 08:10:31AM -0800, Darin Adler wrote:
On Tuesday, December 17, 2002, at 06:44 AM, Michael Brinkmann wrote:
Is there an elegant way to get the shared_ptr pointing to "this" from "this", which would be the solution to the fault?
Yes. There is a relatively new feature in the latest versions of shared_ptr, shared_from_this.
The way you use it in Boost 1.29.0 is to the class you want to store a pointer to inherit from boost::counted_base. You can use multiple inheritance if you already have another base class. Then you can use shared_from_this to turn a raw pointer to this class into a shared_ptr. I expect this feature is going to be in future versions of shared_ptr, but the name of the class you have to inherit from may change.
I just tried this on my own code and have the problem where now some of my classes are being destroyed twice and crashing. What prevents a class inherting from counted_base from doing this? I have my own implementation called smart_ptr which is based on smart_ptr and weak_ptr, which is used in pretty much the same way. public MyClass: public smart_class<MyClass> { ... } It has the advantage of being able to use 'this' without shared_from_this(this), and it doesn't destroy itself twice. The code is here if anyone is interested http://intolerance.digitalpassage.com/misc/smart_ptr.h I thought inheriting from counted_base would make this unnecessary though, shouldn't it? -- Stephen

From: "Stephen Crowley" <stephenc@digitalpassage.com> [...]
I have my own implementation called smart_ptr which is based on smart_ptr and weak_ptr, which is used in pretty much the same way.
public MyClass: public smart_class<MyClass> { ... }
The next Boost release will (likely) contain a similar helper, see: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/s mart_ptr/enable_shared_from_this.html?rev=1.1

On Tue, Dec 17, 2002 at 07:53:52PM +0200, Peter Dimov wrote:
From: "Stephen Crowley" <stephenc@digitalpassage.com> [...]
I have my own implementation called smart_ptr which is based on smart_ptr and weak_ptr, which is used in pretty much the same way.
public MyClass: public smart_class<MyClass> { ... }
The next Boost release will (likely) contain a similar helper, see:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/s mart_ptr/enable_shared_from_this.html?rev=1.1
Cool, this is exactly what I was looking for, how long has it been around? -- Stephen

From: "Stephen Crowley" <stephenc@digitalpassage.com>
On Tue, Dec 17, 2002 at 07:53:52PM +0200, Peter Dimov wrote:
From: "Stephen Crowley" <stephenc@digitalpassage.com> [...]
I have my own implementation called smart_ptr which is based on smart_ptr and weak_ptr, which is used in pretty much the same way.
public MyClass: public smart_class<MyClass> { ... }
The next Boost release will (likely) contain a similar helper, see:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/s
mart_ptr/enable_shared_from_this.html?rev=1.1
Cool, this is exactly what I was looking for, how long has it been around?
It's a relatively recent addition. You can see the revision history at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/boost/enable_shar ed_from_this.hpp

Hi Darin, Stephen, Peter,
Yes. There is a relatively new feature in the latest versions of shared_ptr, shared_from_this.
The way you use it in Boost 1.29.0 is to the class you want to store a pointer to inherit from boost::counted_base. You can use multiple inheritance if you already have another base class. Then you can use shared_from_this to turn a raw pointer to this class into a shared_ptr. I expect this feature is going to be in future versions of shared_ptr, but the name of the class you have to inherit from may change. it works perfect. Thank you!
bye Michael
participants (4)
-
Darin Adler
-
Michael Brinkmann
-
Peter Dimov
-
Stephen Crowley