2

I'm working on a bit of a thought experiment here -- I'm trying to actually make my life easier here. I'm working with a data structure that, among other things, contains a couple of arrays of elements that are kept in sorted order. I allocate these data structures in fixed-size blocks to make for easier memory placement, and also to (at a future time) make for easier reading/writing from stable storage. Here is the code I'm working with so far:

#include <limits> const int NODE_SIZE = 512; template <typename K, typename D> class Node { long next; short num; K* keys; D* data; public: Node( int l, int order ); }; // num is calculated by something like this... num = NODE_SIZE - sizeof( Node<K,D> ) - sizeof( long ); num /= (sizeof( D ) + sizeof( K )); // Constructor // Will be called with a placement-new and given a NODE_SIZE // byte block of memory, aligned at NODE_SIZE template<typename K, typename D> Node<K,D>::Node( int n ) : num ( n ), next( 0 ) { keys = reinterpret_cast<K*>(reinterpret_cast<char*>(&next) + sizeof( *this )); int numbytes = num*sizeof(K); // Make sure we're aligned to a void *. if ( numbytes % sizeof( void * ) ) { numbytes = (numbytes / sizeof( void * )+1)*sizeof( void * ); } // Align to the number of bytes in a void * data = reinterpret_cast<D*>( reinterpret_cast<char*>(keys)+numbytes); for( int i=0; i<num; i++ ) keys[i] = std::numeric_limits<K>::max(); } 

Since the elements in key are in sorted order, I would really like to be able to use a std::vector and std::vector so I can use somebody else's vector insertion code instead of writing my own (not that it's hard, but why reinvent the wheel?).

Also, is there a cleaner way of setting up my pointers for keys and data? Any assistance or suggestions would be welcome.

4
  • Do you know about allocators? Commented Jun 18, 2013 at 19:20
  • I know that they exist, but I have yet to make use of them. Commented Jun 18, 2013 at 19:25
  • 1
    I believe you can do what you want to do by providing a std::vector with an allocator. I'm not certain, because I neither understand exactly what you are doing, nor do I fully understand allocators, but my ignorance matches where I think you and allocators overlap. :) Commented Jun 18, 2013 at 19:27
  • You can certainly use placement new to put a std::vector at a specific address, but that would only put the vector's member variables (typically three pointers and a possibly-empty allocator) into that memory, the vector's elements would be stored separately in memory obtained from its allocator. As the comment above says, you could use a custom allocator that is initialized with a pointer to the storage you've already allocated, and which returns pointers to that memory when requested to allocate memory, but doing so is surprisingly complicated and difficult to get right, unfortunately. Commented Jul 11, 2013 at 10:32

1 Answer 1

2

Your calculation for num:

(NODE_SIZE - sizeof( Node<K,D> ) - sizeof( long )) / (sizeof( D ) + sizeof( K )) 

is notably compile-time constant. Why not simply declare:

template <typename K, typename D> class BpTreeNode { static const std::size_t num = (NODE_SIZE - sizeof( long )) / (sizeof( D ) + sizeof( K )); K keys[num]; D data[num]; long next; public: Node( int l, int order ); }; 

and let the compiler do the work for you?

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.