Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard library facilities which allocate but don't use an Allocator

In most places where the C++ standard library allocates memory, the user is able to customise this by providing a class which meets the Allocator requirements. For example, almost all containers take an allocator template argument, and std::allocate_shared returns a shared_ptr whose contained element and control block are both allocated via a provided Allocator.

However, there are a few places where the standard library can (potentially) allocate memory, but no Allocator support is provided. The ones I can think of are:

  • std::make_unique() (no corresponding allocate_unique())
  • std::any
  • std::function (allocator support will be removed in C++17)
  • std::valarray
  • std::basic_filebuf (although std::basic_stringbuf does use an Allocator)
  • std::inplace_merge()

Questions:

  • I'm sure this list is incomplete, but what else have I missed?
  • Of the non-Allocator classes and functions, are they specified to use global ::operator new, plain new, or is the memory source unspecified?
  • If anybody knows, what are the reasons for not providing allocator support in any, and removing it from function?
like image 639
Tristan Brindle Avatar asked Mar 27 '17 20:03

Tristan Brindle


1 Answers

Not an exhaustive list.

  • Everything in <stdexcept>, which needs to allocate memory to store the message string.
  • The standard pool/monotonic memory resource classes obviously allocate memory, but they do it from another memory resource, not an allocator, so they technically fit your description.
  • boyer_moore_searcher and boyer_moore_horspool_searcher.
  • Several <algorithm> algorithms attempt to obtain additional memory (e.g., stable_partition, stable_sort) and all parallel algorithms (regardless of header) may need additional memory.
  • Many things in the filesystem library:
    • path; that one used to use the default allocator internally, but looks like the newest draft removed that requirement, although it seems to be the intent still.
    • directory_iterator and recursive_directory_iterator.
    • Some filesystem operations that can construct temporary paths .
  • basic_­regex.
  • thread and async.
  • packaged_task, allocator support removed in C++17.
  • promise will need somewhere to put the shared state.
  • iostreams.
  • Many things are hard-coded to use the default allocator:
    • error_code::message(), error_condition::message(), error_category::message(): these return a string, so default allocator only.
    • bitset's stream insertion operator notionally calls to_string with the default allocator, though no high-quality implementation would do that in practice.
    • The to_string and to_wstring free functions return std::string/std::wstring respectively; no chance to specify your own allocator. Obviously the user-defined literals for string (e.g., "foo"s) also have no custom allocator support.
    • There are several facets in <locale> that have member functions returning either std::string or std::basic_string<charT>, i.e., using the default allocator (e.g., numpunct), or accepting only basic_string<charT> (e.g., money_get).
    • Various types in <random> uses a vector with the default allocator.

If anybody knows, what are the reasons for not providing allocator support in any, and removing it from function?

any's allocator support is unimplementable. function's allocator support is poorly specified and plagued with issues.

like image 112
T.C. Avatar answered Oct 19 '22 03:10

T.C.