quiZ___
quiZ___

Reputation: 119

Proper way to prevent deallocation using std::allocator and std::move

As the title says, I wonder if this is a proper way to prevent deallocation in vector<T> a when moving vector<T> a tovector<T> b.

Vector header:

template<class T, class A = std::allocator<T>>
class vector
{
    typedef typename A::size_type size_type;

    A alloc;
    T* start;
    T* end;

    public:

            explicit vector(size_type n, const T& val = T(), const A& =A());
            vector(vector&&);
            ~vector();

};

Constructor:

Note: allocate can throw std::bad_alloc.

template<class T, class A>
vector<T,A>::vector(size_type n, const T& val, const A& a)
    : alloc(a)
{

    start = alloc.allocate(n); //allocate memory for n elements.
    end = start + n;

    for(auto p = start; p!=end; p++)
            alloc.construct(p, val); //construct val at allocated memory.

}

Move constructor:

Question: Is this a proper way to move vector v?

template<class T, class A>
vector<T,A>::vector(vector&& v)
    :alloc(v.alloc)             // copy the allocator in v.
{

    start = std::move(v.start); // move the pointer previously returned by allocator. 
    end = std::move(v.end);     // same boundary value.
    v.start = v.end = nullptr;  // nullptr to prevent deallocation when v is destroyed.
}

Destructor:

Question: According to cppreference, allocator::deallocate(p, n) deallocates memory from a pointer previously returned by allocator and n must be equal to the number of elements allocated for. What if this is not the case? My answer would be that allocator::deallocate does nothing if the pointer or the number of elements, n, is not equal to previous call to allocator::allocate(n). Is this true?

template<class T, class A>
vector<T, A>::~vector()
{
    for(auto p = start; p!=end; p++)
            alloc.destroy(p);           //Destroy objects pointed to by alloc. 

    alloc.deallocate(start, end-start); //Deallocate memory.
}

Upvotes: 1

Views: 454

Answers (1)

eerorika
eerorika

Reputation: 238361

Is this a proper way to move vector v?

Seems fine, but std::move is redundant with pointers. Also, you don't deallocate end, so you don't need to set it to null.

What if this is not the case? My answer would be that allocator::deallocate does nothing if the pointer or the number of elements, n, is not equal to previous call to allocator::allocate(n). Is this true?

No, the behaviour is undefined. You must pass the same n.

Upvotes: 1

Related Questions