为什么我的 C++11 分配器的 dtor 被调用了两次?

Why is my C++11 allocator's dtor called twice?

我编写了我自己的基本 c++11 分配器来分解它,看看它是如何工作的。大部分事情进展顺利,但由于某种原因,我的 dtor 被调用了两次。现在这不是问题,但我可以想象一个场景,有状态分配器在第二次调用 dtor 时尝试取消引用 nullptr,所以我很好奇这是否是预期的行为,如果是,有没有办法避免它?

代码如下:

#include<iostream>
#include<vector>
#include<new>

using std::vector;
using std::cout;
using std::endl;
using __gnu_cxx::ptrdiff_t;

template<typename elem_t>
struct myAlloc {
    typedef elem_t value_type;
    typedef elem_t * pointer;
    typedef const elem_t * const_pointer;
    typedef elem_t & reference;
    typedef const elem_t & const_reference;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    template<typename other_elem_t>
    struct rebind {
        typedef myAlloc<other_elem_t> other;
    };

    myAlloc() {
        cout << "constructing myAlloc" << endl;
    }
    ~myAlloc() {
        cout << "destructing myAlloc" << endl;
    }
    pointer address(reference x) const {
        cout << "myAlloc retrieving address" << endl;
        return &x;
    }
    const_pointer address(const_reference x) const {
        cout << "myAlloc retrieving address of x" << endl;
        return &x;
    }
    pointer allocate(size_type n, const void * hint = 0) {
        cout << "myAlloc allocating n elem_t's" << endl;
        pointer retval = (pointer)malloc(n * sizeof(value_type));

        if (retval == nullptr)
            throw std::bad_alloc();
        return retval;
    }
    void deallocate(pointer p, size_type n) {
        cout << "myAlloc deallocating n elem_t's" << endl;
        free(p);
    }
    size_type max_size() const throw() {
        return -1;
    }
    void construct(pointer p, const_reference val) {
        cout << "Constructing an elem_t 'val' at address p" << endl;
        new ((void*)p) value_type (val);
    }
    void destroy(pointer p) {
        cout << "Destroying the elem_t at address p" << endl;
        p->~value_type();
    }
};  

void test() {
    cout << "creating vec" << endl;
    vector<int, myAlloc<int> > myvec = {1, 2, 3, 4, 5};
    cout << "done creating vec" << endl;
}   
int main() {
    test();
    cout << "main" << endl;
}

这是输出:

creating vec
constructing myAlloc
myAlloc allocating n elem_t's
Constructing an elem_t 'val' at address p
Constructing an elem_t 'val' at address p
Constructing an elem_t 'val' at address p
Constructing an elem_t 'val' at address p
Constructing an elem_t 'val' at address p
destructing myAlloc
done creating vec
Destroying the elem_t at address p
Destroying the elem_t at address p
Destroying the elem_t at address p
Destroying the elem_t at address p
Destroying the elem_t at address p
myAlloc deallocating n elem_t's
destructing myAlloc  
main

我的猜测是分配器在使用时在本地构造,并在分配完对象后立即销毁。但是尽管分配器被破坏,我们还是调用了 destroydeallocate 函数。为什么要这样实现?分配完成后立即销毁分配器有什么用?在一般情况下,在解除分配后调用成员函数如何不会破坏事情?

答案已发布在评论中。分配器构造两次,一次用于分配,一次用于释放。谢谢@T.C。用于解决方案和@ivaigult 用于实现