samedi 20 janvier 2018

placement new with different types in preallocated memory - how to guarantee alignment?

I'm trying to build a class that can be used as some sort of shared pointer. For performance reasons I'd like to implement a factory function that allocates the memory for the object and a unsigned int reference counter in a single step:

template<typename T> class SharedPointer {

  uint8_t* buffer;
  T* obj;
  unsigned int* counter;

  template<typename Args...> static SharedPointer make(Args&&... args) {
    SharedPointer p;
    p.buffer = new uint8_t[sizeof(T) + sizeof(unsigned int)];
    p.obj = new (p.buffer) T(std::forward<Args>(args)...);
    p.counter = new (p.buffer + sizeof(T)) unsigned int(1);
    return p;
  }

}

And later, when the shared object is about to be deleted:

~SharedPointer() {
  *counter--;
  if (*counter == 0) {
    obj->~T();
    delete[] buffer;
  }
}

The question is: is it necessary to set the correct memory alignment for the allocated buffer and how can this be achieved? I know the keyword alignas, but I don't know how it should be integrated here.

Aucun commentaire:

Enregistrer un commentaire