Is there a C ++ alternative for posix_memalign?

When I call posix_memalignto allocate aligned memory for an object of type Fooin my C ++ code, I need to make a reinterpret_castaddress of this pointer to void**.

In general, when I come across this situation, it means that I am missing some language features. That is, it seems to me that I call mallocin c++when I need to call new. Is there an equivalent equivalent newto the type for allocating allocated memory in c++?

+4
source share
3 answers

First, I will start with a basic tip.

Foo* aligned_foo() {
  void* raw = 0;
  if(posix_memalign(&raw, 8, sizeof(Foo)))
    return 0; // we could throw or somehow communicate the failure instead
  try{
    return new(raw) Foo();
  }catch(...){
    free(raw);
    throw;
  }
}

then when you are done with Foo* foo, do foo->~Foo(); free(foo);instead delete.

reinterpret_cast s.


:

// note: stateless.  Deleting a derived with a base without virtual ~base a bad idea:
template<class T>
struct free_then_delete {
  void operator()(T*t)const{
    if(!t)return;
    t->~T();
    free(t);
  };
};
template<class T>
using aligned_ptr=std::unique_ptr<T,free_then_delete<T>>;

// the raw version.  Dangerous, because the `T*` requires special deletion:
template<class T,class...Args>
T* make_aligned_raw_ptr(size_t alignment, Args&&...args) {
  void* raw = 0;
  if(int err = posix_memalign(&raw, alignment, sizeof(T)))
  {
    if (err==ENOMEM)
      throw std::bad_alloc{};
    return 0; // other possibility is bad alignment: not an exception, just an error
  }
  try {
    // returns a T*
    return new(raw) T(std::forward<Args>(args)...);
  } catch(...) { // the constructor threw, so clean up the memory:
    free(raw);
    throw;
  }
}
template<class T,class...Args> // ,class... Args optional
aligned_ptr<T> make_aligned_ptr(size_t alignment=8, Args&&...args){
  T* t = make_aligned_raw_ptr<T>(alignment, std::forward<Args>(args)...);
  if (t)
    return aligned_ptr<T>(t);
  else
    return nullptr;
}

unique_ptr aligned_ptr - , , . .release() , .

+4

, reinterpret_cast, Foo . , :

void* alloc;
posix_memalign(&alloc, 8, sizeof(Foo));
Foo* foo = new (foo) Foo();

(pre ++ 11) - new . , , :

class Foo {
    void* operator new(size_t size) {
        void* newobj;
        posix_memalign(&newobj, 8, sizeof(Foo));
        return newobj;
    }
};

, new Foo(), . . http://en.cppreference.com/w/cpp/memory/new/operator_new. operator new operator delete .

+3

++ 11 .

alignas(N) ++ 11, , new .

cppreference:

struct alignas(16) sse_t { // SSE-safe struct aligned on 16-byte boundaries
    float v[4];
};

sse_t *ssevec = new sse_t;

posix_memalign std::aligned_storage<sizeof(T), N>, ++ 11.

+2

All Articles