简体   繁体   English

使用std :: allocator和std :: move防止重新分配的正确方法

[英]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 to vector<T> b . 如标题所述,我想知道这是在将vector<T> a移到vector<T> b时防止在vector<T> a重新分配的一种正确方法。

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 . 注意: allocate可以抛出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? 问题:这是移动向量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. 问题:根据cppreferenceallocator::deallocate(p, n)从先前由allocator返回的指针中释放内存,并且n必须等于为其分配的元素数。 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) . 我的回答是,如果指针或元素数n不等于先前对allocator::allocate(n)调用,则allocator::deallocate不执行任何操作。 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.
}

Is this a proper way to move vector v? 这是移动向量v的正确方法吗?

Seems fine, but std::move is redundant with pointers. 看起来不错,但是std::move在指针上是多余的。 Also, you don't deallocate end , so you don't need to set it to null. 另外,您无需取消分配end ,因此无需将其设置为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). 我的答案是,如果指针或元素数n不等于先前对allocator :: allocate(n)的调用,则allocator :: deallocate不执行任何操作。 Is this true? 这是真的?

No, the behaviour is undefined. 不,行为是不确定的。 You must pass the same n . 您必须传递相同的n

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM