Call constructor for object array allocated with malloc()

c, c++, constructor, memory-management, oop

Solution

Do `new (pointerT) T()` in a loop. Please keep `pointerT` inside an object whose destructor destroys the objects and calls `free` (call it eg. `aligned_vector`), and in the constructor, do:

ptrdiff_t k = 0;

try
{
    for (; k < n; k++)
        new (pointerT + k) T();
}

catch (...)
{
    for (; k > 0; k--) (pointerT + k)->~T();
    free(pointerT);
    throw;
}

This way, if a construction fails, you can bail out transactionally and not leak memory or resources.

For this purpose, the simplest in terms of reusability would be to implement your own alignment aware allocator and use `std::vector`, which takes care of exception safety (and many other goodies) for you.

Here is a sample allocator, C++11, with compile time alignment specification (please suggest enhancements and corrections):

template <typename T, size_t align>
struct aligned_allocator
{
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    template <typename U>
    struct rebind { typedef aligned_allocator<U, align> other; };

    T* address(T& t) { return &t; }

    T* allocate(size_t n, const T* = 0) 
    {
        if (T* ans = memalign(align, n * sizeof(T))) return ans;
        else throw std::bad_alloc();
    }

    T* deallocate(T* p, size_t) { free(p); }

    size_t max_size() const 
    {
        return size_t(-align) / sizeof(T); 
    }

    template <typename U, typename... Args>
    void construct(U* p, Args&&... args)
    {
        ::new((void *)p U(std::forward<Args>(args)...);
    }

    template <typename U>
    void destroy(U* p) { p->~U(); }
};

Sample usage: `std::vector<T, aligned_allocator<T, 64>> v(42);` constructs a vector with aligned storage and 64 elements.

You can also do, in C++11

template <typename T, size_t align>
using aligned_vector = std::vector<T, aligned_allocator<T, align>>;

and you can now use

aligned_vector<MyType, 64> v;

and enjoy an exception safe, move aware, iterators aware, range-based-for-loop aware, etc, vector with aligned storage.

Problem

Possible Duplicate: Can placement new for arrays be used in a portable way? I want to allocate array of object T and initialize object using object constructor. This is easy using c++ `new` : ``` T * pointerT = new T [arraySize]; ``` It will call T constructor for all of the `arraySize` objects. However, for some reason I have to use C `memalign` instead of new. In this case I end up to use following code ``` T * pointerT = (T*) memalign(64,arraySize * sizeof(T)); new (pointerT) T(); ``` `new (pointerT) T()` calls T constructor only one time. However, I need to call T constructor for all objects not only the first one. I do appreciate your help.

Original source

Related problems