Распределитель C ++ по умолчанию - что должно произойти, если размер не равен размеру, переданному вызову allocate? - PullRequest
6 голосов
/ 21 июля 2011

20.6.9:

void deallocate(pointer p, size_type n);
  • Требуется: p должно быть значением указателя, полученным из allocate (). n должен приравнять значение, переданное в качестве первого аргумента к вызову allocate, который возвратил p.
  • Эффекты: освобождает память, на которую ссылается p.
  • Примечания: Использует :: оператор delete (void *) (18.6.1), но он не указан при вызове этой функции.

Что должно произойти, если n не равно значению, переданному в качестве первого аргумента для вызова allocate, который возвратил p? Не сдавать? Бросить std::bad_alloc? ...

EDIT: На самом деле я имел в виду «что должно произойти»: было бы нормально бросать или утверждать в пользовательской реализации?

Ответы [ 3 ]

10 голосов
/ 21 июля 2011

Как обычно в C ++ Standard, когда ничего явно не указано, нарушение требований приводит к неопределенному поведению. Обязательно означает, что всегда должно , это требование, а не опция в C ++ Standard.

Например, вот что MSDN говорит :

Указатель _Ptr должен был быть возвращен ранее вызовом для выделения объекта распределителя, который сравнивается равным * this, выделяя объект массива того же размера и типа.

, что означает, что размер должен точно соответствовать, иначе вы столкнетесь с неопределенным поведением.

3 голосов
/ 21 июля 2011

Это не говорит. Это означает, что это будет неприятный «неопределенный бэвиур».

1 голос
/ 21 июля 2011

Это присутствует в стандарте, чтобы разрешить базовые распределители, которые не знают размер выделения из своего указателя.

Например, распределитель AmigaOS поддерживает список свободных блоков памяти и даже допускает частичное освобождение (т. Е. Если я выделяю 1024 байта, то освобождаю 512 байтов со смещением 256, в результате я получаю два выделения 256 байтов), поэтому распределитель ожидает, что я передам эту информацию в распоряжение.

...