Alexander Oh
Alexander Oh

Reputation: 25631

How to avoid temporary object on the stack when using the allocator concept?

The following code tries to create nodes of a binary tree and return a boost::shared_ptr() to it.

void create_node(shared_ptr &in,
            unsigned var_name,
            shared_ptr left=shared_ptr(),
            shared_ptr right=shared_ptr()) {
  typename nodes::pointer p = A.allocate(1);
  // a temporary node element is created on the stack here.
  A.construct(p, (node(var_name, left, right)));
  in = shared_ptr(p);
}

Looking into the libstdc++ code I've found out that the std::allocator functions I'm calling look like this:

pointer
allocate(size_type __n, const void* = 0)
{ 
  if (__n > this->max_size())
    std::__throw_bad_alloc();
  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}

void 
construct(pointer __p, const _Tp& __val) 
{ ::new((void *)__p) _Tp(__val); }

The allocator uses in-placement new to separate the allocation of the memory and the construction of the object. Thus it's possible to get a large amount of elements and calls only the constructor when an object is really needed.

The create_node function creates a single object by using the allocator concept and uses shared_ptr to call the destructor whenever needed. To make these single allocations cheap I want to replace the allocator later (hence I want an allocator that uses pool allocation).

When I call this function it will create a temporary instance on the stack and then copies the elements of the node to heap location. How can I force the compiler to create the object in place immediately? Thus I want an inverted Named Return Value Optimization (NRVO). Is this possible?

Upvotes: 2

Views: 356

Answers (1)

jpalecek
jpalecek

Reputation: 47762

You could use allocate_shared.

Upvotes: 3

Related Questions