
Hi everyone,
I've been investigating our program's memory usage, and one of the spots
that I keep seeing the stack hitting its limit is when using
boost::make_shared.
I've written a simple test program, that completes fine when I use new...
but fails with a stack overflow when I use boost::make_shared
========================
#include <iostream>
#include

Michael Xu wrote:
Hi everyone,
I've been investigating our program's memory usage, and one of the spots that I keep seeing the stack hitting its limit is when using boost::make_shared.
I've written a simple test program, that completes fine when I use new... but fails with a stack overflow when I use boost::make_shared ======================== #include <iostream> #include
#include using namespace std; struct arr { char arg[1024*1024]; }; struct test { struct arr array[1024]; };
int main() { test * myTest = new test(); //complete! if (!myTest) cout << "new alloc failed"; boost::shared_ptr<test> testPtr = boost::make_shared<test>(); //fails with stack overflow! if (!testPtr) { cout << "alloc failed;"; } } ===========================
If you run this with a reasonable thread stack of 8 megabytes, it fails when using boost::make_shared.
Here is the stack trace.....
#0 boost::shared_ptr<test>::shared_ptr
(test*, boost::detail::sp_ms_deleter<test>) () #1 boost::shared_ptr<test> boost::make_shared<test>() () #2 main () Is there a reason this happens?
Do you mean heap rather than stack? You are first allocating with new: 1024 * 1024 * 1024 = 1,073,741,824 = 1GB of contiguous memory. Then your attempting to allocate another 1GB with make_shared. This has a good chance of failing on 32bit windows systems. You don't mention the OS. I would expect that make_shared is throwing an exception like std::bad_alloc which you are not cathing. Jeff

Actually, I put both methods with new and make_shared in there to illustrate
the point.
When I run it JUST with new. It completes. When I run it JUST with
make_shared it fails.
I'm also running on a x86_64 linux machine with 6 gb of ram.
I asked this on the #boost channel on freenode.net, everyone thought I was
confusing stack with heap as well.. but that's not the case... comparing the
stack pointers in each frame using "info register' in gdb tells me that the
space used by the frames in that stack trace are unreasonably large.
On Sat, Feb 5, 2011 at 9:47 PM, Jeff Flinn
Michael Xu wrote:
Hi everyone,
I've been investigating our program's memory usage, and one of the spots that I keep seeing the stack hitting its limit is when using boost::make_shared. I've written a simple test program, that completes fine when I use new... but fails with a stack overflow when I use boost::make_shared ======================== #include <iostream> #include
#include using namespace std; struct arr { char arg[1024*1024]; }; struct test { struct arr array[1024]; };
int main() { test * myTest = new test(); //complete! if (!myTest) cout << "new alloc failed"; boost::shared_ptr<test> testPtr = boost::make_shared<test>(); //fails with stack overflow! if (!testPtr) { cout << "alloc failed;"; } } ===========================
If you run this with a reasonable thread stack of 8 megabytes, it fails when using boost::make_shared.
Here is the stack trace..... #0 boost::shared_ptr<test>::shared_ptr
(test*, boost::detail::sp_ms_deleter<test>) () #1 boost::shared_ptr<test> boost::make_shared<test>() () #2 main () Is there a reason this happens?
Do you mean heap rather than stack?
You are first allocating with new:
1024 * 1024 * 1024 = 1,073,741,824 = 1GB of contiguous memory.
Then your attempting to allocate another 1GB with make_shared. This has a good chance of failing on 32bit windows systems. You don't mention the OS.
I would expect that make_shared is throwing an exception like std::bad_alloc which you are not cathing.
Jeff
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Michael Xu (770)634-1738 Computer Science Georgia Tech

On 6 Feb 2011, at 03:00, Michael Xu wrote:
Actually, I put both methods with new and make_shared in there to illustrate the point.
When I run it JUST with new. It completes. When I run it JUST with make_shared it fails.
I'm also running on a x86_64 linux machine with 6 gb of ram.
I asked this on the #boost channel on freenode.net, everyone thought I was confusing stack with heap as well.. but that's not the case... comparing the stack pointers in each frame using "info register' in gdb tells me that the space used by the frames in that stack trace are unreasonably large.
I am not knowledgable about the inner details of boost::shared_ptr, but the problem is that: boost::detail::sp_ms_deleter<test> Is as big as test, and make_shared allocates one of those on the stack, in line: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); Chris

2011/2/6 Christopher Jefferson
boost::detail::sp_ms_deleter<test>
Is as big as test, and make_shared allocates one of those on the stack, in line:
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T
() );
Chris
This looks like a very interesting drawback of make_shared, that never occoured to me. The deleter contains space for the allocated object inside itself, and is passed by value, therefore the allocated object must be small enough to fit on the stack, when using make_shared. Is this a known thing (bug)? Regards, Kris.

I checked my little example above... It's actually using 2 gb on the stack... plus 1 gb on the heap. Both frame 0 and frame 1 seem to have 1gb. On Sun, Feb 6, 2011 at 7:16 AM, Krzysztof Czainski <1czajnik@gmail.com>wrote:
2011/2/6 Christopher Jefferson
boost::detail::sp_ms_deleter<test>
Is as big as test, and make_shared allocates one of those on the stack, in line:
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
Chris
This looks like a very interesting drawback of make_shared, that never occoured to me. The deleter contains space for the allocated object inside itself, and is passed by value, therefore the allocated object must be small enough to fit on the stack, when using make_shared.
Is this a known thing (bug)?
Regards, Kris.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Michael Xu (770)634-1738 Computer Science Georgia Tech

On Sunday, February 06, 2011, Krzysztof Czainski wrote:
This looks like a very interesting drawback of make_shared, that never occoured to me. The deleter contains space for the allocated object inside itself, and is passed by value, therefore the allocated object must be small enough to fit on the stack, when using make_shared.
Is this a known thing (bug)?
https://svn.boost.org/trac/boost/ticket/4256 I think to fix it would require adding a special shared_ptr constructor for make_shared to use, which default constructs the deleter instead of copying the deleter in as a constructor argument.
participants (5)
-
Christopher Jefferson
-
Frank Mori Hess
-
Jeff Flinn
-
Krzysztof Czainski
-
Michael Xu