Aart Stuurman
Aart Stuurman

Reputation: 3598

Initialize heap array from other array

How do I create an array on the heap and initialize it at construction time from another array?

template <typename T>
T* Copy(T* myOriginalArray, size_t myOriginalArraySize)
{
    T* copy = new T[myOriginalArraySize]; // copy data from myOriginalArray here too
    return copy;
}

I could create the array and then use std::copy, but this would require the array contents to have an empty constructor. You can assume the object has a copy and move constructor. I have access to C++17.

Upvotes: 0

Views: 108

Answers (2)

Passer By
Passer By

Reputation: 21150

You use ::operator new and std::uninitialized_copy

#include<memory>
#include<new>

template<typename T>
T* Copy(T* src, size_t sz)
{
    auto buf = static_cast<T*>(::operator new(sizeof(T) * sz));
    std::uninitialized_copy(src, src + sz, buf);
    return buf;    
}

And possibly move, with a bit more hassle.

#include<utility>

template<typename T>
T* Move(T* src, size_t sz)
{
    auto buf = static_cast<T*>(::operator new(sizeof(T) * sz));
    for(size_t i = 0; i < sz; i++)
        new (buf + i) T(std::move(src[i]));
    return buf;
}

This is not really a great idea, considering then you have to deallocate with some crazy code

template<typename T>
void Delete(T* src, size_t sz)
{
    for(size_t i = 0; i < sz; i++)
        src[i].~T();
    ::operator delete(src);
}

Do consider using std::vector instead.

Side note

Q: Why index with size_t instead of using T*?
A: As it turns out, it is currently slightly faster with indexing.

Upvotes: 2

javidcf
javidcf

Reputation: 59711

Not sure if this is what you are asking, but you can just allocate the memory first and then use placement new (which is basically what preallocating STL containers do anyway).

template <typename T>
T* Copy(T* myOriginalArray, size_t myOriginalArraySize)
{
    auto t_size = sizeof(T);
    T* copy = (T *) new char[myOriginalArraySize * t_size];
    for (size_t i = 0; i < myOriginalArraySize; i++)
    {
        new (copy + i) T(*(myOriginalArray + i));
    }
    return copy;
}

Upvotes: 0

Related Questions