Reputation: 119
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
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