libc++源码分析之std::allocator

std::allocator

默认的内存分配器,负责内存的分配和销毁

函数

allocate

分配内存

1
2
3
4
5
6
7
8
9
10
11
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
const _Tp* allocate(size_t __n) {
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
if (__libcpp_is_constant_evaluated()) {
return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
} else {
return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
}

deallocate

销毁内存

1
2
3
4
5
6
7
8
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(const _Tp* __p, size_t __n) {
if (__libcpp_is_constant_evaluated()) {
::operator delete(const_cast<_Tp*>(__p));
} else {
_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
}
}

rebind

1
2
3
4
template <class _Up>
struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
typedef allocator<_Up> other;
};

address

引用的地址

1
2
3
4
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
const_pointer address(const_reference __x) const _NOEXCEPT {
return _VSTD::addressof(__x);
}

max_size

对象最大分配的数量

1
2
3
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
return size_type(~0) / sizeof(_Tp);
}

construct

调用对象的指定参数的构造函数

1
2
3
4
5
template <class _Up, class... _Args>
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
void construct(_Up* __p, _Args&&... __args) {
::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
}

destroy

调用对象的析构函数

1
2
3
4
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
void destroy(pointer __p) {
__p->~_Tp();
}

std::allocator_traits

允许自定义allocator实现,std::allocator只是默认实现,std::allocator_traits定义了allocator接口,自定义的allocator需要满足std::allocator_traits。

对于使用者来说,比如vector,会用std::allocator_traits来调用外部传递进来的allocator,而不会直接去使用allocator。

1
2
3
4
5
6
template <class _Alloc>
struct _LIBCPP_TEMPLATE_VIS allocator_traits
{
using allocator_type = _Alloc; // 具体的allocator实现
using value_type = typename allocator_type::value_type; // allocator管理的对象类型
};

函数

allocate

通过allocator_traits来调用allocator的allocate函数

1
2
3
4
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
static pointer allocate(allocator_type& __a, size_type __n) {
return __a.allocate(__n);
}

deallocate

通过allocator_traits来调用allocator的deallocate函数

1
2
3
4
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT {
__a.deallocate(__p, __n);
}