Skip to content

Latest commit

 

History

History
143 lines (117 loc) · 5.26 KB

allocators.md

File metadata and controls

143 lines (117 loc) · 5.26 KB
descriptiontitlems.datehelpviewer_keywords
Learn more about: Allocators
Allocators
11/04/2016
allocators
C++ Standard Library, allocators

Allocators

Allocators are used by the C++ Standard Library to handle the allocation and deallocation of elements stored in containers. All C++ Standard Library containers except std::array have a template parameter of type allocator<Type>, where Type represents the type of the container element. For example, the vector class is declared as follows:

template < classType, classAllocator = allocator<Type> > classvector

The C++ Standard Library provides a default implementation for an allocator. In C++11 and later, the default allocator is updated to expose a smaller interface; the new allocator is called a minimal allocator. In particular, the minimal allocator's construct() member supports move semantics, which can greatly improve performance. In most cases, this default allocator should be sufficient. In C++11 all the Standard Library types and functions that take an allocator type parameter support the minimal allocator interface, including std::function, shared_ptr, allocate_shared(), and basic_string. For more information on the default allocator, see allocator Class.

Writing Your Own Allocator (C++11)

The default allocator uses new and delete to allocate and deallocate memory. If you want to use a different method of memory allocation, such as using shared memory, then you must create your own allocator. If you are targeting C++11 and you need to write a new custom allocator, make it a minimal allocator if possible. Even if you have already implemented an old-style allocator, consider modifying it to be a minimal allocator in order to take advantage of the more efficient construct() method that will be provided for you automatically.

A minimal allocator requires much less boilerplate and enables you to focus on the allocate and deallocate member functions, which do all of the work. When creating a minimal allocator, do not implement any members except the ones shown in the example below:

  1. a converting copy constructor (see example)

  2. operator==

  3. operator!=

  4. allocate

  5. deallocate

The C++11 default construct() member that will be provided for you does perfect forwarding and enables move semantics; it is much more efficient in many cases than the older version.

Warning

At compile time, the C++ Standard Library uses the allocator_traits class to detect which members you have explicitly provided and provides a default implementation for any members that are not present. Do not interfere with this mechanism by providing a specialization of allocator_traits for your allocator!

The following example shows a minimal implementation of an allocator that uses malloc and free. Note the use of the new exception type std::bad_array_new_length which is thrown if the array size is less than zero or greater than the maximum allowed size.

#pragma once #include<stdlib.h>//size_t, malloc, free #include<new>// bad_alloc, bad_array_new_length #include<memory>template <classT> structMallocator { typedef T value_type; Mallocator() noexcept {} //default ctor not required by C++ Standard Library// A converting copy constructor:template<classU> Mallocator(const Mallocator<U>&) noexcept {} template<classU> booloperator==(const Mallocator<U>&) constnoexcept { returntrue; } template<classU> booloperator!=(const Mallocator<U>&) constnoexcept { returnfalse; } T* allocate(constsize_t n) const; voiddeallocate(T* const p, size_t) constnoexcept; }; template <classT> T* Mallocator<T>::allocate(constsize_t n) const { if (n == 0) { returnnullptr; } if (n > static_cast<size_t>(-1) / sizeof(T)) { throwstd::bad_array_new_length(); } void* const pv = malloc(n * sizeof(T)); if (!pv) { throwstd::bad_alloc(); } returnstatic_cast<T*>(pv); } template<classT> void Mallocator<T>::deallocate(T * const p, size_t) constnoexcept { free(p); }

Writing Your Own Allocator (C++03)

In C++03, any allocator used with C++ Standard Library containers must implement the following type definitions:

:::row::: :::column::: const_pointer
const_reference :::column-end::: :::column::: difference_type
pointer :::column-end::: :::column::: rebind
reference :::column-end::: :::column::: size_type
value_type :::column-end::: :::row-end:::

In addition, any allocator used with C++ Standard Library containers must implement the following methods:

:::row::: :::column::: Constructor
Copy constructor
Destructor :::column-end::: :::column::: address
allocate
construct :::column-end::: :::column::: deallocate
destroy
max_size :::column-end::: :::column::: operator!=
operator== :::column-end::: :::row-end:::

For more information on these type definitions and methods, see allocator Class.

See also

C++ Standard Library Reference

close