
On 4/9/2011 12:55 PM, Peter Dimov wrote:
Phil Bouchard wrote:
http://www.fornux.com/personal/philippe/devel/shifted_ptr/libs/smart_ptr/doc...
"If it is found to be living on the heap then a more complicated mechanism is involved to track the last memory block that was allocated in the same thread, find its address and stack up the set it will be part of until the first shifted_ptr<T> found on the stack is or data segment is initialized, where the new set counter will be shared with all of the newly allocated blocks of memory referencing each other."
This doesn't seem very robust. If you have
struct X { std::vector< shifted_ptr<A> > v_; };
struct Y { shifted_ptr<A> p_; };
and then do something like
X * px = new X; // heap allocation #1 px->v_.reserve( 5 ); // heap allocation #2 Y * py = new Y; // heap allocation #3 py->p_.reset( new A ); // heap allocation #4 px->v_.push_back( py->p_ ); // no heap allocation
I see no way for the last shifted_ptr instance (px->v_[0]) to be associated with heap allocation #1 or #2, where it belongs.
(If the allocation isn't made with "new shifted<>" then the member pointers will be treated as if they were living on the stack. This is because "new shifted<>" uses its own pool and only memory blocks allocated within this pool are recognized to be living on the heap.) If for example you used: struct X { std::vector< shifted_ptr<A>, shifted_allocator< shifted_ptr<A> > > v_; }; struct Y { shifted_ptr<A> p_; }; shifted_ptr<X> px = new shifted<X>(); // heap allocation #1 px->v_.reserve( 5 ); // heap allocation #2 shifted_ptr<Y> py = new shifted<Y>(); // heap allocation #3 py->p_.reset( new shifted<A>() ); // heap allocation #4 px->v_.push_back( py->p_ ); // no heap allocation #5 Then we have 2 sets created by #1 and #3 that are unified by the last operation #5. The last operation constructs a shifted_ptr living in set 1 with another shifted_ptr living in set 2. Set 1 and 2 are therefore merged. -Phil