Существуют ли какие-либо функции или классы в стандартной библиотеке C ++, которые гарантированно не выполняют динамическое выделение памяти? - PullRequest
0 голосов
/ 09 января 2019

Существуют контексты, в которых мы хотим, чтобы наш код C ++ не выполнял динамическое выделение памяти («в куче»), особенно в некоторых случаях использования встроенных разработок.

Существуют стандартные библиотечные классы, которые могут быть реализованы без динамического выделения памяти: необязательно, массив, кортеж, вариант, чтобы назвать несколько. То же самое верно и для стандартных библиотечных функций.

Существуют ли такие классы или функции, которые гарантированы стандартом для динамического выделения памяти? Единственные функции, которые я мог найти с такой гарантией, - это размещение функций new ().

1 Ответ

0 голосов
/ 09 января 2019

В очень редких случаях стандарт C ++ дает прямую гарантию отказа от использования динамической памяти.

В системах, где динамическое распределение памяти небезопасно для сигнала, вы можете быть уверены, что все функции, перечисленные как безопасные для сигнала, не выделяются. Стандарт упоминает

_Exit
abort
forward
initializer_list functions
memcpy
memmove
move
move_if_noexcept
numeric_limits members
quick_exit
signal
type traits
plain lock-free atomic operations

Если вы можете предполагать соответствие другому стандарту, POSIX, тогда в нем перечислены другие функции, async-signal-safe . Некоторые из этих функций, перечисленных в POSIX, также предусмотрены стандартами C ++ (и C) (например, strcat), и поэтому эти стандартные функции C ++ будут безопасны для сигналов во всех системах POSIX.

В [new.delete.placement] есть несколько функций, которые по определению не выделяются.


Другой вопрос, отдельный от гарантий, заключается в том, будет ли разумная реализация функции или типа не распределяться. Многие, многие вещи, такие как std::tuple и std::array (естественно, с нераспределенными аргументами типа) попадают в эту категорию.

Было бы разумно, чтобы функции, которые объявлены noexcept и не имели пути ошибки (например, установка кода ошибки, возвращение значения ошибки или завершение процесса), не должны распределяться, так как распределение может вызвать выброс.

И наоборот, есть функции, которые в разумной реализации выделяют динамическую память. Очевидно, что те, которые связаны с распределителями, а также перечисленные в SO post , который вы связали. Одна неочевидная, которая часто кусает людей, пишущих обработчики сигналов, отсутствует в списке: совсем не разумно ожидать, что printf или любая из связанных с ней функций не будут выделяться.

...