Стандартный совместимый пользовательский распределитель - PullRequest
7 голосов
/ 20 мая 2011

Можно ли создавать исключение, когда 0 передается методу allocate?

Спасибо.

PS

Если n == 0,возвращаемое значение не указано.

Означает ли это, что allocate не должно вызывать исключение?Я склонен думать, что если бы бросок не был разрешен для n == 0, то стандарт четко прописал бы его.

Ответы [ 2 ]

7 голосов
/ 20 мая 2011

Все, что говорит стандарт (§20.1.5 / 2), это то, что дано

  • T - любой тип
  • X - Распределитель класс для типа T
  • a - значение типа X&
  • n - значение типа X::size_type,

возвращаемое значение выражения a.allocate(n) равно не указано , если n равно 0.

Одной рукой, учитывая, что X::allocate не имеет обязательной спецификации исключенийи явно может выбросить std::bad_alloc, я не понимаю, почему он не может генерировать и другие типы исключений.С другой стороны, формулировка специально вызывает условие, при котором n равно нулю, и прямо подразумевает, что является возвращаемым значением, то есть вы не должны бросать.Я думаю, что это может быть открыто для некоторой интерпретации, но лично я бы встал на сторону последнего и счел бы это неисключительным путем кода.

6 голосов
/ 20 мая 2011

Стандарт требует, чтобы при выделении размера 0 возвращался указатель на блок памяти размером 1 байт, Brb, при поиске соответствующего параграфа стандартов.


Редактировать
Во-первых, мне пригодился только FDIS C ++ 0x / 11 (не дома ...), но я считаю, что формулировка была похожа на C ++ 98/03.

Далее, похоже, я ошибался. Нигде не указано, что распределитель должен возвращать блок памяти размером 1. Моя память послужила мне неправильно. :( Хотя я нашел этот маленький абзац в 3.7.4.2 [basic.stc.dynamic.allocation] p2:

Даже если размер запрошенного пространства равен нулю, запрос может завершиться ошибкой. Если запрос выполнен успешно, возвращаемое значение должно быть ненулевым значением указателя (4.10) p0, отличным от любого ранее возвращенного значения p1, если только это значение p1 не было впоследствии передано оператору delete. Эффект разыменования указателя, возвращаемого как запрос нулевого размера, не определен. 35)

В конце того же сайта:

35) Цель состоит в том, чтобы оператор new () мог быть реализован путем вызова std :: malloc () или std :: calloc (), поэтому правила по существу тот же самый. C ++ отличается от C тем, что требует нулевого запроса для возврата ненулевого указателя.

(Акцент мой.)

Теперь FDIS сообщает в 17.6.3.5 [allocator.requirements] в примечании к allocate:

a.allocate(n)     X::pointer 

Память выделена для n объектов типа T, но объекты не построены. allocate может выдвинуть соответствующее исключение. [Примечание: если n == 0, возвращаемое значение не указано. —Конечная записка]

(Акцент мой.)
Таким образом, вы не должны бросать, поскольку возвращение что-то подразумевается этой запиской. Однако не требуется возвращать блок памяти размером 1 байт. Итак, чтобы ответить на ваш вопрос: Нет, вы не можете добавить allocate, если размер запроса равен 0 при реализации стандартного совместимого распределителя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...