使用 std::分配器和 std::move 防止释放的正确方法

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

本文关键字:std 方法 释放 分配器 move 使用      更新时间:2023-10-16

正如标题所说,我想知道这是否是在将vector<T> a移动到vector<T> b时防止vector<T> a中释放的正确方法。

矢量标头:

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();
};

构造 函数:

注意:分配可以抛出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.
}

移动构造函数:

问题:这是移动向量 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.
}

破坏者:

问:根据 cpp 首选项,allocator::deallocate(p, n)从先前由 allocator 返回的指针中释放内存,并且n必须等于为其分配的元素数。如果不是这种情况怎么办?我的回答是,如果指针或元素的数量n不等于先前对allocator::allocate(n)的调用,则allocator::deallocate什么也不做。这是真的吗?

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.
}

这是移动向量 v 的正确方法吗?

看起来不错,但指针std::move多余。此外,您不会释放end,因此无需将其设置为 null。

如果不是这种情况怎么办?我的答案是,如果指针或元素数 n 不等于之前对 allocator::allocate(n) 的调用,则 allocator::d eassign 不执行任何操作。这是真的吗?

不,行为是未定义的。您必须通过相同的n