Пространства имён
Варианты
Действия

std::allocator

Материал из cppreference.com
< cpp‎ | memory
 
 
Динамическое управление памятью
no section name
Ограниченные алгоритмы неинициализированной памяти
no section name
allocator
Поддержка сбора мусора
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)
(C++11)(до C++23)



no section name
 
std::allocator
Функции-элементы
(до C++20)
(до C++20)
Функции, не являющиеся элементами
 
Определено в заголовочном файле <memory>
template< class T >
struct allocator;
(1)
template<>
struct allocator<void>;
(2) (устарело в C++17)
(удалено в C++20)

Шаблонный класс std::allocator является Allocator по умолчанию и используется всеми контейнерами стандартной библиотеки, если не указан пользовательский аллокатор. Аллокатор по умолчанию не имеет состояния, то есть все экземпляры данного аллокатора взаимозаменяемы, равны и могут освобождать память, выделенную любым другим экземпляром аллокатора того же типа.

В явной специализации для void отсутствуют определения типов элементов reference, const_reference, size_type и difference_type. Эта специализация не объявляет никаких функций-элементов.

(до C++20)

Распределитель по умолчанию соответствует требованиям к полноте аллокатора.

(начиная с C++17)

Содержание

[править] Типы-элементы

Тип Определение
value_type T
pointer (устарело в C++17)(удалено в C++20) T*
const_pointer (устарело в C++17)(удалено в C++20) const T*
reference (устарело в C++17)(удалено в C++20) T&
const_reference (устарело в C++17)(удалено в C++20) const T&
size_type std::size_t
difference_type std::ptrdiff_t
propagate_on_container_move_assignment(C++11) std::true_type
rebind (устарело в C++17)(удалено в C++20) template< class U >

struct rebind
{
    typedef allocator<U> other;
};

is_always_equal(C++11)(устарело в C++23) std::true_type

[править] Функции-элементы

создаёт новый экземпляр аллокатора
(public функция-элемент) [править]
уничтожает экземпляр аллокатора
(public функция-элемент) [править]
(до C++20)
получает адрес объекта, даже если operator& перегружен
(public функция-элемент) [править]
выделяет неинициализированное хранилище
(public функция-элемент) [править]
выделяет неинициализированное хранилище как минимум такого же размера, как запрошенный размер
(public функция-элемент) [править]
освобождает память
(public функция-элемент) [править]
(до C++20)
возвращает наибольший поддерживаемый размер распределения
(public функция-элемент) [править]
(до C++20)
создаёт объект в выделенном хранилище
(public функция-элемент) [править]
(до C++20)
уничтожает объект в выделенном хранилище
(public функция-элемент) [править]

[править] Функции, не являющиеся элементами

(удалено в C++20)
сравнивает два экземпляра аллокатора
(public функция-элемент) [править]

[править] Примечание

Шаблонный класс элемента rebind предоставляет способ получить аллокатор для другого типа. Например, std::list<T, A> распределяет узлы некоторого внутреннего типа Node<T>, используя аллокатор A::rebind<Node<T>>::other (до C++11)std::allocator_traits<A>::rebind_alloc<Node<T>>, который реализуется в терминах A::rebind<Node<T>>::other, если A является std::allocator (начиная с C++11).

Тип элемента is_always_equal устарел в следствии LWG проблема 3170, поскольку он делает пользовательские распределители, производные от std::allocator, по умолчанию всегда равными. std::allocator_traits<std::allocator<T>>::is_always_equal не устарел, а его константа-элемент value равна true для любого T.

[править] Пример

#include <memory>
#include <iostream>
#include <string>
 
int main()
{
    // аллокатор по умолчанию для int
    std::allocator<int> alloc1;
 
    // демонстрация нескольких непосредственно используемых элементов
    static_assert(std::is_same_v<int, decltype(alloc1)::value_type>);
    int* p1 = alloc1.allocate(1); // место для одного int
    alloc1.deallocate(p1, 1);     // и его больше нет
 
    // Их даже можно использовать через свойства, но нет такой необходимости
    using traits_t1 = std::allocator_traits<decltype(alloc1)>; // Соответствующее свойство
    p1 = traits_t1::allocate(alloc1, 1);
    traits_t1::construct(alloc1, p1, 7);  // создаём int
    std::cout << *p1 << '\n';
    traits_t1::deallocate(alloc1, p1, 1); // освободить место для одного int
 
    // аллокатор по умолчанию для строк
    std::allocator<std::string> alloc2;
    // соответствующее свойство
    using traits_t2 = std::allocator_traits<decltype(alloc2)>;
 
    // Перепривязка аллокатора с помощью свойства для строк получает тот же тип
    traits_t2::rebind_alloc<std::string> alloc_ = alloc2;
 
    std::string* p2 = traits_t2::allocate(alloc2, 2); // место для 2 строк
 
    traits_t2::construct(alloc2, p2, "foo");
    traits_t2::construct(alloc2, p2 + 1, "bar");
 
    std::cout << p2[0] << ' ' << p2[1] << '\n';
 
    traits_t2::destroy(alloc2, p2 + 1);
    traits_t2::destroy(alloc2, p2);
    traits_t2::deallocate(alloc2, p2, 2);
}

Вывод:

7
foo bar

[править] Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
LWG 2103 C++11 может потребоваться избыточное сравнение между allocator предоставлено
propagate_on_container_move_assignment
LWG 2108 C++11 не было способа показать, что allocator не имеет состояния предоставлено is_always_equal

[править] Смотрите также

предоставляет информацию о типах аллокаторов
(шаблон класса) [править]
реализует многоуровневый аллокатор для многоуровневых контейнеров
(шаблон класса) [править]
проверяет, поддерживает ли указанный тип конструирование с uses_allocator
(шаблон класса) [править]