Оператор new
(или для POD, malloc / calloc) поддерживает простую и эффективную форму отказа при выделении больших блоков памяти.
Допустим, у нас есть следующее:
const size_t sz = GetPotentiallyLargeBufferSize(); // 1M - 1000M
T* p = new (nothrow) T[sz];
if(!p) {
return sorry_not_enough_mem_would_you_like_to_try_again;
}
...
Есть ли такая конструкция для std :: container, или мне всегда придется обрабатывать (ожидаемое !!) исключение с помощью std :: вектор
и друзья?
Может быть, есть способ написать собственный распределитель, который предварительно выделяет память, а затем передает этот пользовательский распределитель вектору, чтобы вектор не запрашивал больше памяти, чем вы поместить в распределитель заранее, он не потерпит неудачу?
Запоздалые мысли : Что действительно было бы необходимо, так это функция-член bool std :: vector :: reserve (std :: nothrow) {...}
в дополнение к нормальной резервной функции. Но так как это имело бы смысл только в том случае, если бы распределители также были расширены, чтобы разрешить бессрочное распределение, этого просто не произойдет. Кажется, (nothrow) new все-таки хорош для чего-то: -)
Edit: Что касается почему я даже спрашиваю это:
Я думал над этим вопросом во время отладки (1-й шанс / 2-й случайная обработка исключений отладчика): Если я ' Я установил свой отладчик на 1-й шанс поймать любой bad_alloc, потому что я тестирую на условиях нехватки памяти, было бы неприятно, если бы он также поймал те исключения bad_alloc, которые уже ожидаются и обрабатываются в коде. Это не было / не было большой проблемой, но мне просто пришло в голову, что в проповеди говорится, что исключения предназначены для исключительных обстоятельств, и что-то, что я уже ожидал, каждый нечетный вызов в коде не является исключением.
Если new (nothrow)
имеет свое законное использование, также будет иметь место вектор-nothrow-reserve.