Newbie shared_ptr in a container question.
I've been reading through posts on here and in the docs but I think I may have missed something. Heres what I am trying to do: lets say I have a class Foo* and I'm trying to use it in a std::vector<shared_ptr<Foo> >. I can add them all day long and it works fine. The problem is that when I try to remove the shared_ptr from the vector. I expected it to delete the memory for the Foo* then delete itself (to completely free the memory that the shared_ptr used and the memory that the Foo was using. I think this is not happening though since the destructor is not being called when the elements are removed from the vector. Heres how I am currently inserting the shared_ptr's into the vector (yes I know this is the wrong way now that I've read a few of the posts here): typedef std::vector<boost::shared_ptr<Foo> > FooVector; FooVector Foobar; Foo* blah = new Foo(); boost::shared_ptr<Foo> * NewPointer = new boost::shared_ptr<Foo>(blah); Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its probably wrong. When I call Foobar.erase() I thought that the shared_ptr would be removed and the memory freed (and Foo's destructor called). I tried it like this : FooVector::iterator CurrentFoo = Foobar.begin(); Foobar.erase(CurrentFoo); That did remove the shared_ptr but the Foo* did not seem to get deallocated, its destructor was never called. Some of the posts seem to indicate that this is a very bad way to let shared_ptr manager the memory, is there a better way to do what I want to do using shared_ptr or is shared_ptr the wrong tool to use?
Joshua wrote:
I've been reading through posts on here and in the docs but I think I may have missed something. Heres what I am trying to do: lets say I have a class Foo* and I'm trying to use it in a std::vector<shared_ptr<Foo> >. I can add them all day long and it works fine. The problem is that when I try to remove the shared_ptr from the vector. I expected it to delete the memory for the Foo* then delete itself (to completely free the memory that the shared_ptr used and the memory that the Foo was using. I think this is not happening though since the destructor is not being called when the elements are removed from the vector. Heres how I am currently inserting the shared_ptr's into the vector (yes I know this is the wrong way now that I've read a few of the posts here):
typedef std::vector<boost::shared_ptr<Foo> > FooVector;
FooVector Foobar; Foo* blah = new Foo(); boost::shared_ptr<Foo> *> NewPointer = new boost::shared_ptr<Foo>(blah); Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its probably wrong.
Yes, that's your mistake. You don't need to do a new of a shared_ptr<>, and you are leaking that memory anyway, which means you are losing one of the references to the shared object. Your code can simply look like this: typedef std::vector<boost::shared_ptr<Foo> > FooVector; FooVector Foobar boost::shared_ptr<Foo> NewPointer(new Foo()); Foobar.insert(NewPointer); -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org
On Sat, 2003-07-26 at 20:57, Joshua wrote: Hi
typedef std::vector<boost::shared_ptr<Foo> > FooVector;
FooVector Foobar; Foo* blah = new Foo(); boost::shared_ptr<Foo> * NewPointer = new boost::shared_ptr<Foo>(blah); Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its probably wrong.
The above isn't quite right. You're inserting pointers to shared_ptr's. Try this instead: typedef std::vector<boost::shared_ptr<Foo> > FooVector; FooVector Foobar; Foobar.push_back( new Foo(blah) ); -- Regards Paul Paul Grenyer Email: pjgrenyer@iee.org Web: www.paulgrenyer.co.uk EvaneScence: http://www.evanescence.com
Paul Grenyer <pjgrenyer@iee.org> writes:
On Sat, 2003-07-26 at 20:57, Joshua wrote:
Hi
typedef std::vector<boost::shared_ptr<Foo> > FooVector;
FooVector Foobar; Foo* blah = new Foo(); boost::shared_ptr<Foo> * NewPointer = new boost::shared_ptr<Foo>(blah); Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its probably wrong.
The above isn't quite right. You're inserting pointers to shared_ptr's. Try this instead:
typedef std::vector<boost::shared_ptr<Foo> > FooVector; FooVector Foobar; Foobar.push_back( new Foo(blah) );
That won't work either; shared_ptr's constructor is explicit. you could write Foobar.push_back(boost::shared_ptr<Foo>(new Foo(blah))) But Peter Dimov's excellent advice is "manage every newly-allocated resource immediately with a *named* resource manager object" (e.g. shared_ptr), leading to: boost::shared_ptr<Foo> myfoo(new Foo(blah)); Foobar.push_back(myfoo); -- Dave Abrahams Boost Consulting www.boost-consulting.com
--- At Sat, 26 Jul 2003 19:57:17 +0000, Joshua wrote:
I've been reading through posts on here and in the docs but I think I may have missed something. Heres what I am trying to do: lets say I have a class Foo* and I'm trying to use it in a std::vector<shared_ptr<Foo> >. I can add them all day long and it works fine. The problem is that when I try to remove the shared_ptr from the vector. I expected it to delete the memory for the Foo* then delete itself (to completely free the memory that the shared_ptr used and the memory that the Foo was using. I think this is not happening though since the destructor is not being called when the elements are removed from the vector. Heres how I am currently inserting the shared_ptr's into the vector (yes I know this is the wrong way now that I've read a few of the posts here):
typedef std::vector<boost::shared_ptr<Foo> > FooVector;
FooVector Foobar; Foo* blah = new Foo(); boost::shared_ptr<Foo> * NewPointer = new boost::shared_ptr<Foo>(blah); Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its probably wrong.
When I call Foobar.erase() I thought that the shared_ptr would be removed and the memory freed (and Foo's destructor called). I tried it like this : FooVector::iterator CurrentFoo = Foobar.begin(); Foobar.erase(CurrentFoo);
That did remove the shared_ptr but the Foo* did not seem to get deallocated, its destructor was never called. Some of the posts seem to indicate that this is a very bad way to let shared_ptr manager the memory, is there a better way to do what I want to do using shared_ptr or is shared_ptr the wrong tool to use?
There have been many good suggestions as to what the correct sequence for inserting the shared_ptr into the vector. I'm not sure the real problem has been adequately explained. Why isnt the foo* being deleted. Shared_ptr<> counts the number of instances of the pointer that are created. When you did: boost::shared_ptr<Foo> * NewPointer = new boost::shared_ptr<Foo>(blah); You created the first instance; count == 1. When you did: Foobar.insert(*NewPointer); //Yes I know this looks horrible. And its A copy of the shared_ptr<> was made. The count is now 2. When you did: Foobar.erase(CurrentFoo); One copy (of two) was "deleted". In this sense, the shared_ptr<> was deleted. The destructor for the shared counter mearly decrements the counter. Count == 1. The problem is that the original count was leaked by using "new shared_ptr<>". This is why all the suggestions show that you should be using the stack based method for shared_ptr<>. Shared_ptr is almost never allocated from the heap. There really is not much point. It's use is as a value representation of pointer. I hope this helps you understand where your code went astray. Good luck, ...Duane ...Duane
participants (5)
-
David Abrahams
-
Duane Murphy
-
Jon Biggar
-
Joshua
-
Paul Grenyer