我编写了自己的基本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
我的猜测是,分配器只要在使用时就在本地构建,并在分配完对象后立即进行破坏。但是,尽管分配器被破坏,我们仍然会调用destroy
和deallocate
函数。为什么这样实现?分配完成后如何破坏分配器有用吗?如何在解除分配后调用成员函数不会破坏一般情况下的事情?
答案 0 :(得分:0)
答案发表在评论中。分配器构造两次,一次用于分配,一次用于解除分配。谢谢@ T.C.为解决方案和@ivaigult实施